[Python-Dev] nano-threads?

Neil Schemenauer nas@arctrix.com
Mon, 26 Mar 2001 21:08:24 -0800


Here are some silly bits of code implementing single frame
coroutines and threads using my frame suspend/resume patch.
The coroutine example does not allow a value to be passed but
that would be simple to add.  An updated version of the (very
experimental) patch is here:

    http://arctrix.com/nas/generator3.diff

For me, thinking in terms of frames is quite natural and I didn't
have any trouble writing these examples.  I'm hoping they will be
useful to other people who are trying to get their mind around
continuations.  If your sick of such postings on python-dev flame
me privately and I will stop.  Cheers,

  Neil

#####################################################################
# Single frame threads (nano-threads?).  Output should be:
#
# foo
# bar
# foo
# bar
# bar

import sys

def yield():
    f = sys._getframe(1)
    f.suspend(f)

def run_threads(threads):
    frame = {}
    for t in threads:
        frame[t] = t()
    while threads:
        for t in threads[:]:
            f = frame.get(t)
            if not f:
                threads.remove(t)
            else:
                frame[t] = f.resume()


def foo():
    for x in range(2):
        print "foo"
        yield()

def bar():
    for x in range(3):
        print "bar"
        yield()

def test():
    run_threads([foo, bar])

test()

#####################################################################
# Single frame coroutines.  Should print:
#
# foo
# bar
# baz
# foo
# bar
# baz
# foo
# ...

import sys

def transfer(func):
    f = sys._getframe(1)
    f.suspend((f, func))

def run_coroutines(args):
    funcs = {}
    for f in args:
        funcs[f] = f
    current = args[0]
    while 1:
        rv = funcs[current]()
        if not rv:
            break
        (frame, next) = rv
        funcs[current] = frame.resume
        current = next


def foo():
    while 1:
        print "foo"
        transfer(bar)

def bar():
    while 1:
        print "bar"
        transfer(baz)
        transfer(foo)