[Stackless] sleep idiom -- 100% CPU core load could be easily eliminated for the cost of negligible latency

Richard Tew richard.m.tew at gmail.com
Thu Mar 27 20:36:46 CET 2014


Hi,

The sleep idiom is just an stripped down specific case.  It can't
handle, and shouldn't handle, this sort of thing.

The reason is that it is more complicated.  The user is likely using a
lot of other things and often the yield to the operating system can be
incorporated into a call to something like poll() or select() or
whatever.  The length of the next awakening sleeper can be factored
into this yield length.

If the developer isn't able to determine how to go about this
themselves, depending on their needs, then they are perhaps best to
use something like stacklesslib - which if it doesn't fully cover
this, perhaps should.

Cheers,
Richard.

On 3/28/14, Valery Khamenya <khamenya at gmail.com> wrote:
> Hi all,
>
> there is a section "Sleeping / Idiom - Sleep function for general use:" on
> the page http://www.stackless.com/wiki/Idioms
>
> The unwanted full load on the CPU core running the scheduler could be
> avoided for the cost of tiny (and perhaps negligible) latency:
>
> ############## Start
> import stackless, time
>
> 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(maxLatency=0.005):
>     while 1:
>         if len(sleepingTasklets):
>             endTime = sleepingTasklets[0][0]
>             toWait = endTime - time.time()
>             if toWait <= 0:
>                 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)
>                 continue
>             else:
>                 toWait = min(toWait, maxLatency)
>         else:
>             toWait = maxLatency
>         time.sleep(toWait)
>         stackless.schedule()
>
> stackless.tasklet(ManageSleepingTasklets)()
>
> def TestSleep():
>     print "pre", time.time()
>     Sleep(5.0)
>     print "post", time.time()
>
> stackless.tasklet(TestSleep)()
> stackless.run()
>
> ############## End
>
> Remarks:
>  * Tested with pypy-2.2.1 only
>  * With the code above the load on the CPU core is never coming above 1%
> after the tasks are completed (100% in original version), and is about 1%
> when waiting for the second task.
>  * The camel-case naming is preserved.
>  * Currently there is a typo in this section on the web-site, where example
> is given the ':' is missing after 'TestSleep()'
>
> best regards
> --
> Valery Khamenya
>



More information about the Stackless mailing list