[Stackless] Why can't I use nanosleep() to suspend the execution of a stackless tasklet?

Richard Tew richard.m.tew at gmail.com
Thu Sep 19 22:14:30 CEST 2013


What Stackless offers, is the ability to hide the work done on other
threads behind normal looking function calls.  You still have to know
it is there, and to account for the fact that calls to these functions
may block the current tasklet, but otherwise you can write more
readable normal looking code.  This is what channels are most commonly
used for.

This is a rather contrived example, in practice it is better to
monkey-patch the socket module:

  channel = stackless.channel()

  def tasklet_connect(host):
      # Actual stacklesslib API may differ.
      stacklesslib.call_on_thread(network_connect, host, channel)
      return channel.receive()

  # This gets called on a worker thread.
  def network_connect(host, channel):
      # Actual networking calls that start connection and wait for it
to complete.
      result = blocking_connect(host)
      channel.send(result)

I reiterate, Kristjan Valur has a library that is primarily used at
CCP Games, which provides lots of useful functionality like
"call_on_thread".  But putting that aside for the moment, note that
tasklets are tied to the thread they were created on.   This means
that when 'tasklet_connect' on the main thread starts
'network_connect' on the worker thread, when the worker thread in
'network_connect' does the 'channel.send' it detects that the tasklet
waiting on 'channel' belongs to another thread, and awakens that
tasklet, the 'tasklet_connect' tasklet, on the main thread where it
belongs with the sent result.  Now something to be wary of, is that
every Python thread has a Stackless scheduler.  Most people just
create tasklets on the main thread, but if you don't write your code
properly, you can create tasklets on other threads where you are not
running the scheduler.  Not that anyone ever does this, but it helps
illuminate how things are actually set up.

Back to stacklesslib.  It features monkey-patching.  I don't know that
it covers multiprocessing yet, but it covers the socket module, it
covers the threading modules, the locks and what-not.  It can make all
those modules just work on the tasklet level, and for a whole range of
basic standard library behaviour take care of delegating work to other
threads making the patched standard library code just block on the
tasklet level, instead of the thread level.  Maybe it also needs to
handle monkey-patching this nanosleep method, if that's part of the
standard library.

Cheers,
Richard.



More information about the Stackless mailing list