I’ve gathered together some of the recent Python code I’ve been playing with into a single file, concurrency.py. At present this contains support for MultiEvents, MultiQueues, AsyncResults, DataflowDicts and DataflowObjects.
MultiEvent is a class that lets you listen for several events at once, and tells you when any one of them has been set. MultiQueue lets you wait for an item to be available in any of several queues. When an item arrives, it tells you what the item is and what queue it was in. An AsyncResult represents a computation running on a separate thread that might not have finished yet (very like IAsyncResult in the .Net framework). The threaded function transformer/decorator causes a method to run in its own thread and return an AsyncResult.
DataflowDict provides a dictionary of single-assignment variables. If you try to read a variable that hasn’t been assigned yet, it will block until a value becomes available. DataflowObject wraps a DataflowDict, translating attribute gets and sets into dataflow dictionary lookups. Together with threaded, the dataflow classes make some interesting kinds of nondeterministic / declarative concurrency possible. Even with the scaffolding I’ve created, it’s still nowhere near as easy in Python as it is in Oz.
There is more to be done here (including, no doubt, some careful inspection of the code for subtle or egregious threading errors - race conditions, that kind of thing), but I think I’ve made a fairly good start.