Python threading?

Thomas Heller theller at python.net
Thu Sep 26 13:01:09 EDT 2002


Tim Peters wrote:
> [Robert Oschler]
> 
>>Having written _many_ state machines in my life, which async programming
>>boils down to in one form or another, I feel it depends on the task.
>>...
>>Contrast this with a simple procedure call where a linear series of
>>function calls are made, each with appropriate error handling and status
>>adjustment, in a pleasant centrally located manner.
> 
> 
> [Thomas Heller]
> 
>>I wonder if generators can come to a rescue here?
> 
> 
> Absolutely.  Read the start of PEP 255.
> 
> 
>>Still trying to get them into my head...
> 
> 
> Think of them as resumable functions.  You're familiar with functions that
> remember their own data state across calls, via abusing globals, or via
> declaring private static vrbls, in C.  Methods on objects often do the same
> by stuffing their state into instance attributes between calls.  A generator
> remembers its data state across resumptions simply by virtue of that its
> local variables don't vanish, and also remembers its control-flow state
> across resumptions.  Remembering local data state by magic is a real
> convenience, but can be simulated in many other ways with reasonable effort;
> it's the ability to remember and restore control-flow state by magic that
> can make generators more than merely convenient.

I _have_ written kind of hardware descriptions with it - what you do 
with VHDL testbenches normally. This was fun!
There were several generators like this, manipulating clock, reset
and other signals in a counter device. The value yield'ed is simply
the time to wait:

     def run_clock(self):
         while 1:
             self.clock = not self.clock
             yield 50 # wait 50 ns

     def run_reset(self):
         self.reset = 1
         yield 200 # a 200 ns reset pulse
         self.reset = 0

The dispatcher goes like this: Creates the generators,
pushes them onto a priority queue (together with the time
value they will have to be served), serves them by calling
the next() method, and pushes the result back onto the queue:

def run(*gens):
     queue = MyList() # a priority queue
     # insert all generators
     for g in gens:
         queue.put((0, g()))
     # and run them
     while queue:
         now, gen = queue.pop(0)
         try:
             dt = gen.next()
         except StopIteration:
             pass
         else:
             queue.put((now + dt, gen))

--------

OTOH, I've been missing the possibility to pass
values back _to_ the generators - something like maybe
'work = yield event', probably triggered by calling gen.next(work)). 
Wouldn't this be useful?

I fear I cannot explain this clearly, but I think
David Mertz statemachine example would also profit from it.
As I understand it, he passes this 'work' around in global variables.

Thomas




More information about the Python-list mailing list