[Stackless] Invitation to Present at PyCon 2007

Andrew Dalke dalke at dalkescientific.com
Tue Oct 31 19:04:53 CET 2006

Richard Tew wrote:
> As someone who hasn't used threading much, I find linkage
> between threading and what Stackless has to taint Stackless
> with a feeling of complexity.

Hmm.  But as someone who has used threads, all I really use
from them is "make new thread" and Queue.Queue.  That is,
tasklet and a channel.  Okay, and an occasional lock.

> For me tasklets are just some simple utility which lifts
> functions up a level, enabling cleaner, more readable code
> and in conjunction with channels, less boilerplate.  That it
> is a simpler form of threading is something that never
> comes to mind.

Then we have different mental models of threads/stackless.  I
don't follow what you mean by "up a level", etc.  Do you mean
that functions are more .. hefty? exeuction-oriented? more
like a process? more Erlang like, if I understand Erlang.

What boilerplate is saved?

BTW, here's a quick throw together of the mapping I have in my head
concerning the stackless API.  There are differences.  Eg, channel
isn't exactly a Queue.Queue.  I would need P/V semaphores to get the
counts right for "balance", I need some solution to make things
non-preemptive, handle correct scheduling, and more.  But it's
mostly busywork.  The result would take a lot more resources and be
a lot slower (stackless does user-space scheduling and is, I think,
quicker at doing the scheduling than a preemptive scheduler.)

# Hack to get some of the Stackless primitives kinda working with 
# Not to be used for real code.

import threading
import Queue

_unscheduled_tasks = set()

def schedule(task):
     if not task.running:

def run():
     _unsched = list(_unscheduled_tasks)
     for task in _unsched:

class tasklet_thread(threading.Thread):
     def __init__(self):
         self.q = Queue.Queue(1)
     def run(self):
         x = self.q.get()
         if x is None:
         f, args, kwargs = x
         f(*args, **kwargs)

class tasklet(object):
     def __init__(self, f=None):
         self.thread = tasklet_thread()
         self.f = f
         self.run_args = ((), {})
         self.running = False
     def bind(self, f):
         self.f = f
     def setup(self, *args, **kwargs):
         self.run_args = args, kwargs
     def __call__(self, *args, **kwargs):
         self.run_args = args, kwargs
         return self
     def run(self):
         if self.running:
             raise AssertionError("already running")
         self.running = True
         self.thread.q.put( (self.f, self.run_args[0], self.run_args[1]) 

class channel(object):
     def __init__(self):
         self.q = Queue.Queue(1)
     def send(self, x):
     def receive(self):
         return self.q.get()


def aCallable(value):
     print "aCallable:", value

task = tasklet(aCallable)
task.setup("Inline using setup")


import __main__ as stackless

def Sending(channel):
     print "sending"


def Receiving(channel):
     print "receiving"
     print channel.receive()


#print "Channel balance is ",ch.balance


the output is the expected

aCallable: Inline using setup

> But that is probably just me.  The abstract sounds great
> and right on target ignoring that (as any sane person
> probably should). Especially given the impending or
> passed deadline :-)

5 hours until localtime midnight.  10 hours or so until US-EST
midnight.  Only impending.  :)

					dalke at dalkescientific.com

Stackless mailing list
Stackless at stackless.com

More information about the Stackless mailing list