Microthreads without Stackless?
David Mertz, Ph.D.
groups.google at gnosis.cx
Sat Sep 18 14:39:28 EDT 2004
Let me follow up briefly on my last note. I presented a
callstack-in-coroutines example a few moments ago. The was something
like:
from __future__ import generators
cargo = None
def grandma():
yield (MOM, cargo)
def mom():
yield (DAUGHTER, cargo)
yield (GRANDMA, cargo)
def daughter():
yield (MOM, cargo)
GRANDMA, MOM, DAUGHTER = grandma(), mom(), daughter()
scheduler(GRANDMA)
While this system indeed exhibits the desired flow:
grandma -> mom -> daughter -> mom -> grandma -> EXIT
It is also certainly a brittle arrangement. MOM always goes back to
GRANDMA, for example. But in real programs, sometimes GRANDPA wants
to switch to MOM also, and still get control back afterwards (rather
than always giving it over, indirectly, to GRANDMA).
You can perfectly well add this flexibility. It's just a matter of
yielding to "the procedure who passed me control" rather than to some
hardcoded next procedure. Well, to know that info, you have to store
it somewhere. Like, say, in 'cargo'. For example:
from __future__ import generators
cargo = CargoClass()
def grandma():
cargo.MOM_CALLER.append(GRANDMA)
yield MOM
def grandpa():
cargo.MOM_CALLER.append(GRANDPA)
yield MOM
def mom():
yield DAUGHTER
next_proc = cargo.MOM_CALLER.pop()
yield next_proc
def daughter():
next_proc = cargo.DAUGHTER_CALLER.pop()
yield next_proc
GRANDMA, GRANDPA, MOM, DAUGHTER = grandma(), grandpa(), mom(),
daughter()
if prefers_grandpa:
scheduler(GRANDPA)
else:
scheduler(GRANDMA)
Since 'cargo' is now a mutable global, I don't bother passing it
around anymore. Implementation of CargoClass() is left as an
exercise. I'm sure you can make some convenience functions to
simplify the code, if you wish.
Yours, David...
More information about the Python-list
mailing list