[Stackless] Starting in stackless...

Carlos Eduardo de Paula cedepaula at yahoo.com.br
Thu Mar 23 14:35:15 CET 2006


I updated my code a little.. cleaned some things...
but I have one doubt... do I need 2 channels... one
for the producer and one for the consumer to control
the chain? Only one channel wouldn´t take care of it
all?

Thanks,

Carlos

------------------ Code ------------------

import stackless
import time

# This is one way to do a time delay in Stackless
while allowing
# other tasklets to run.
def delay(seconds):
     startTime = time.clock()
     stopTime = startTime + seconds
     while time.clock() < stopTime:
         stackless.schedule()

# The other way to put the tasklet to sleep - from
stackless.com wiki/Idioms
##########################################################
sleepingTasklets = []

def Sleep(secondsToWait):
    channel = stackless.channel()
    endTime = time.time() + secondsToWait
    sleepingTasklets.append((endTime, channel))
    sleepingTasklets.sort()
    # Block until we get sent an awakening
notification.
    channel.receive()

def ManageSleepingTasklets():
    while 1:
        if len(sleepingTasklets):
            endTime = sleepingTasklets[0][0]
            if endTime <= time.time():
                channel = sleepingTasklets[0][1]
                del sleepingTasklets[0]
                # We have to send something, but it
doesn't matter what as it is not used.
                channel.send(None)
        stackless.schedule()

stackless.tasklet(ManageSleepingTasklets)()

##########################################################

def printStatus(reporter):
     print reporter + "[" + "#" * len(queue) + " " *
(q_size-len(queue))  + "] Qty:" , len(queue) , "\r",
     time.sleep(0.1)  # so we have time to see the
displayed data
     # keep in mind that this call to time.sleep will
stall
     # all tasklets until time.sleep returns

def producer(who):
     while True:
         if (len(queue) < q_size):
             queue.append("a")
             p_counter[int(who)] += 1
             printStatus('P'+who)
             delay(0.1)
#             Sleep(0.2)
         else:
             ch_c.send(None)        
             ch_p.receive()

def consumer(who):
     while True:
        # Check if the producer is blocked and the
queue is low, then wake the producer
#        if ((len(queue) <= 5) and
(producers[len(producers)-1].blocked)):
#            ch_c.receive()
#            ch_p.send(None)
        if (len(queue) >= 1):
            queue.pop()
            c_counter[int(who)] += 1
            printStatus('C'+who)
            delay(0.8)
#            Sleep(0.8)
        else:
            # This is a breeding ground for deadlocks.
            # In this case the producer has almost
definitely
            # called ch_c.send and is blocked.
            # if you call ch_p.send first then both
            # tasklets will be blocked for all
eternity
            # and stackless.run will return
            ch_c.receive()
            ch_p.send(None)


def launch_p (ind):         # Launches and initializes
the producers lists
    producers.append(int(ind))
    p_counter.append(0)
    producers[int(ind)] =
stackless.tasklet(producer)(ind)

def launch_c (ind):         # Launches and initializes
the consumers lists
    consumers.append(int(ind))
    c_counter.append(0)
    consumers[int(ind)] =
stackless.tasklet(consumer)(ind)

#----------------------------------------------------

q_size = 20                 # Defines the queue size
queue = ["a"] * 0           # Defines the queue start
ch_p = stackless.channel()  # Producer channel
ch_c = stackless.channel()  # Consumer channel

producers = []              # List to reference the
producers
consumers = []              # List to reference the
consumers
p_counter = []              # Counter to hold how much
units each producer inserted in queue
c_counter = []              # Counter to hold how much
units each consumer removed from queue

num_prod = 1                # Number of starting
producers
num_cons = 3                # Number of starting
consumers

for p in range(num_prod):
    launch_p(repr(p))

for c in range(num_cons):
    launch_c(repr(c))

try:
    stackless.run()

# Handle the keyboard interruption and prints the
production report

except KeyboardInterrupt:
    print ""
    print "** Detected ctrl-c in the console"
    exit

print
for p in range(0,len(producers)):
    print "Producer", p , "produced: ", p_counter[p]

for c in range(0,len(consumers)):
    print "Consumer", c , "consumed: ", c_counter[c]
        
print "Left in queue: ", len(queue)
print


------------------ Code ------------------


--- Ásgeir Bjarni Ingvarsson <istari at hlekkir.com>
escreveu:

> Hi Carlos.
> 
> First of all welcome to the fun world of Stackless
> Python.
> The first thing that you need to realize is that
> this is not
> actual multithreading, but sometimes the same
> problems may
> pop up (i.e. deadlocks). This is also why you can
> not use
> time.sleep() since it will stall the entire
> interpreter.
> You also have to remember that, if you call receive
> or send
> on a channel, it will block the calling tasklet.
> 
> I played around with your code and came up with the
> following
> code, I have added comments to explain why I have
> chosen a
> particular path.
> ------
> import stackless
> import time
> 
> q_size = 15
> queue = []
> ch_p = stackless.channel()
> ch_c = stackless.channel()
> 
> print ""
> 
> # This is one way to do a time delay in Stackless
> while allowing
> # other tasklets to run.
> def delay(seconds):
>      startTime = time.clock()
>      stopTime = startTime + seconds
>      while time.clock() < stopTime:
>          stackless.schedule()
> 
> def printStatus(reporter):
>      print reporter + "[" + "#" * len(queue) + " " *
> (15-len(queue))  + 
> "]" + "\r",
>      time.sleep(0.1)  # so we have time to see the
> displayed data
>      # keep in mind that this call to time.sleep
> will stall
>      # all tasklets until time.sleep returns
> 
> def producer():
>      while True:
>          if (len(queue) < q_size):
>              queue.append("a")
>              printStatus('P')
>              delay(0.3)
>          else:
>              ch_c.send(None)    	
>              ch_p.receive()
> 
> 
> def consumer():
>      while True:
>          if (len(queue) >= 1):
>              queue.pop()
>              printStatus('C')
>              delay(0.9)
>          else:
>              # This is a breeding ground for
> deadlocks.
>              # In this case the producer has almost
> definitely
>              # called ch_c.send and is blocked.
>              # if you call ch_p.send first then both
>              # tasklets will be blocked for all
> eternity
>              # and stackless.run will return
>              ch_c.receive()
>              ch_p.send(None)
> 
> prod = stackless.tasklet(producer)()
> cons = stackless.tasklet(consumer)()
> 
> stackless.run()
> ------
> 
> Best regards,
> Asgeir
> 
> Carlos Eduardo de Paula wrote:
> > Hello,
> > 
> > I just subscribed in the list.. I´m starting up in
> > stackless and haven´t done much things with
> > multithread so i´m a little confused. 
> > 
> > I created a little program to test the
> > producer/consumer chain.. but with no success...
> maybe
> > someone could give me a hint about how to make it
> > work... or point some documentation about it...
> > 
> > ----------------
> > 
> > import stackless
> > import time
> > 
> > q_size = 15
> > queue = []
> > ch_p = stackless.channel()
> > ch_c = stackless.channel()
> > 
> > print ""
> > 
> > def producer():
> >     while True:
> >         if (len(queue) < q_size):
> >             queue.append("a")
> >             print "P[" + "#" * len(queue) + " " *
> > (15-len(queue))  + "]" + "\r",
> >             time.sleep(0.3)
> >             stackless.schedule()
> >         else:
> >             ch_c.send(None)    	
> >             ch_p.receive()
> > 
> > 
> > def consumer():
> >     while True:
> >         if (len(queue) >= 1):
> >             queue.pop()
> >             print "C[" + "#" * len(queue) + " " *
> > (15-len(queue))  + "]" + "\r",
> >             time.sleep(0.9)
> >             stackless.schedule()
> >         else:
> >             ch_p.send(None)
> >             ch_c.receive()
> > 
> > prod = stackless.tasklet(producer)
> > cons = stackless.tasklet(consumer)
> > 
> > stackless.run()
> > 
> > 
> > ----------------
> > 
> > 
> > Thanks for all,
> > 
> > Carlos
> > 
> > 
> > 	
> > 
> > 
> > 
> > 	
> > 		
> >
>
_______________________________________________________
> 
> > Yahoo! doce lar. Faça do Yahoo! sua homepage. 
> > http://br.yahoo.com/homepageset.html 
> > 
> > 
> > _______________________________________________
> > Stackless mailing list
> > Stackless at stackless.com
> >
> http://www.stackless.com/mailman/listinfo/stackless
> > 
> > 
> > ----------------------------------------
> > This message was checked with
> > SpamAssassin v.3.10 and  ClamWin Antivirus v0.88  
> > 
> 
> 
> 
> ----------------------------------------
> This message was checked with
> SpamAssassin v.3.10 and  ClamWin Antivirus v0.88  
> 
> 
> _______________________________________________
> Stackless mailing list
> Stackless at stackless.com
> http://www.stackless.com/mailman/listinfo/stackless
> 



		
_______________________________________________________ 
Novo Yahoo! Messenger com voz: Instale agora e faça ligações de graça. 
http://br.messenger.yahoo.com/

_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless



More information about the Stackless mailing list