[Stackless] Santa concurrency problem
Brian Zimmer
bzimmer at ziclix.com
Tue Mar 27 03:56:42 CEST 2007
I just want to make sure I understand the ramifications of adding
sleep() to the main thread. If I have the following code I will be
forced to wait until I come out of the time.sleep regardless of
activity on the channel. This sleep implementation works only because
of the particular use case of the Santa problem, correct? I can type
all day long into stdin but the tasklet is only going to display a
character every five seconds.
Is there a tasklet-safe sleep that the default scheduler can handle
appropriately? Also, is mixing threads and tasklets this way meant to
be avoided?
thanks for answering, brian
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
import sys
import time
import thread
import stackless
class Sleep:
def __init__(self):
self.sleepingTasklets = []
stackless.tasklet(self.ManageSleepingTasklets)()
def Sleep(self, secondsToWait):
channel = stackless.channel()
endTime = time.time() + secondsToWait
self.sleepingTasklets.append((endTime, channel))
self.sleepingTasklets.sort()
# Block until we get sent an awakening notification.
channel.receive()
def ManageSleepingTasklets(self):
while True:
if len(self.sleepingTasklets):
endTime = self.sleepingTasklets[0][0]
if endTime <= time.time():
channel = self.sleepingTasklets[0][1]
del self.sleepingTasklets[0]
# We have to send something, but it doesn't matter what as it
is not used.
channel.send(None)
elif stackless.runcount == 1:
# We are the only tasklet running, the rest are blocked on
channels sleeping.
# We can call time.sleep until the first awakens to avoid a
busy wait.
delay = endTime - time.time()
#print "wait delay", delay
time.sleep(delay)
stackless.schedule()
sleep = Sleep()
def ReadOne(ch):
while True:
n = sys.stdin.read(1)
if n == "\n": continue
print "got '%s'" % (n)
ch.send(n)
def ListenOne(ch):
while True:
sleep.Sleep(5)
c = ch.receive()
print "received '%s'" % (c)
channel = stackless.channel()
stackless.tasklet(ListenOne)(channel)
thread.start_new_thread(ReadOne, (channel,))
stackless.run()
-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
On Mar 26, 2007, at 02:25 PM, Carlos Eduardo de Paula wrote:
> I noticed it too when updating the project examples, they have been
> updated in examples project repository, the Santa one has been added
> and the prod-con ones uses the new ManageSleepTasklets function.
>
> Carlos
>
> Visit Stackless Examples Project
> http://code.google.com/p/stacklessexamples/
> Stackless Python - www.stackless.com
>
>
> On 3/26/07, Santiago Gala <sgala at apache.org> wrote:
>> El lun, 26-03-2007 a las 20:20 +0000, Richard Tew escribió:
>>> On 3/26/07, Carlos Eduardo de Paula <carlosedp at gmail.com> wrote:
>>>> What is taking a hit on CPU is the ManageSleepingTasklets tasklet,
>>>> it
>>>> gets that usage in its loop.
>>>>
>>>> What I can do for throttling the cpu usage is put a
>>>> time.sleep(0.001)
>>>> inside the while loop, with it we can have a decent precision on
>>>> time
>>>> (1 milisecond) and having the CPU at low usage...
>>>>
>>>> Maybe Richard can help us out about a cleaner solution on this...
>>>
>>> The Sleep code here is copied from the simple example I wrote.
>>> Unfortunately like most low level Stackless examples it only
>>> really serves to demonstrate what you can do, now how you should
>>> do it in all cases. In the case here, since it is responsible for
>>> awakening tasklets and if it knows none are waking anytime
>>> soon, it is safe to avoid a busy wait by adapting the code to
>>> use time.sleep for the interim.
>>>
>>
>> Cool, this code makes it work with unnoticeable load, while remaining
>> performant (depending on the sleep time of the workers).
>>
>> The only minor nit: I found delay can be negative, so I got an
>> exception. Using max(delay,0) solved it.
>>
>> Regards
>> Santiago
>>
>>> def ManageSleepingTasklets(self):
>>> while True:
>>> if len(self.sleepingTasklets):
>>> endTime = self.sleepingTasklets[0][0]
>>> if endTime <= time.time():
>>> channel = self.sleepingTasklets[0][1]
>>> del self.sleepingTasklets[0]
>>> # We have to send something, but it doesn't matter what as
>>> it is not used.
>>> channel.send(None)
>>> elif stackless.runcount == 1:
>>> # We are the only tasklet running, the rest are blocked on
>>> channels sleeping.
>>> # We can call time.sleep until the first awakens to avoid
>>> a busy wait.
>>> delay = endTime - time.time()
>>> print "wait delay", delay
>>> time.sleep(delay)
>>> stackless.schedule()
>>>
>>> Cheers,
>>> Richard.
>>>
>>> _______________________________________________
>>> Stackless mailing list
>>> Stackless at stackless.com
>>> http://www.stackless.com/mailman/listinfo/stackless
>>
>>
>> _______________________________________________
>> Stackless mailing list
>> Stackless at stackless.com
>> http://www.stackless.com/mailman/listinfo/stackless
>
> _______________________________________________
> Stackless mailing list
> Stackless at stackless.com
> http://www.stackless.com/mailman/listinfo/stackless
>
_______________________________________________
Stackless mailing list
Stackless at stackless.com
http://www.stackless.com/mailman/listinfo/stackless
More information about the Stackless
mailing list