Hendrik van Rooyen wrote: > "robert" <[EMAIL PROTECTED]> wrote: > > >> pushing data objects through an inter-thread queue is a major source for > trouble - as this thread shows again. >> Everybody builds up a new protocol and worries about Empty/Full, > Exception-handling/passing, None-Elements, ... >> I've noticed that those troubles disappear when a functional queue is used - > which is very easy with a functional language like Python. >> For example with > http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/491281 >> >> One would just use a cq=CallQueue() >> >> On the producer side one would just write the functional code one wants to > execute in a target thread: >> cq.call( what_i_want_do_func ) >> >> >> The consumer/receiver thread would just do (periodically) a non-blocking >> >> cq.receive() >> >> >> => Without any object fumbling, protocol worries and very fast. >> >> And note: This way - working with functional jobs - one can also "protect a > piece of critical code" most naturally and specifically for certain threads > without spreading locks throughout the code. >> Even things which are commonly claimed "forbidden" (even when using lots of > locks) can be magically done in perfect order and effectively this way. Think > of > worker threads doing things in the GUI or in master / database owner threads > etc. >> Similarly discrete background thread jobs can be used in a functional style > this way: >> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/491280 >> ( an alternative for the laborious OO-centric threading.Thread which mostly >> is > a lazy copy from Java ) >> or for higher job frequencies by using "default consumer threads" as also > shown in the 1st example of >> http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/491281 >> > > Thank you - had a (very) quick look and I will return to it > later - It is not immediately obvious to my assembler > programmer's mentality - looks like in the one case > the thread starts up, does its job and then dies, and in > the other its a sort of "remote" daemon like engine, > that you can "tell what to do", from "here"... > > Both concepts seem nice and I will try to wrap my head > around them properly. > > So far I have only used dicts to pass functions around > in a relatively unimaginative static jump table like way...
Probably one has just to see that one can a pass a function object (or any callable) around as any other object. Similar to a function address in assembler/C but very comfortable and with the comfort of closures (which automatically hold the status of local variables): def f(): print "hello" def g(func): print "I'll do it ..." func() print "done." def run(x): g(f) a="local variable\n" def h(): b="inner local" print "inner function" print x,a,b g(h) g(lambda:sys.stdout.write(a)) run(1) From there its just natural to not pass dead objects through an inter-thread queue, but just code as it or even a "piece of critical code" ... A small step in thought, but a big step in effect - soon eliminating bunches of worries about queues, pop-races/None objects, protocol, serialization, critical sections, thousands of locks etc. Robert -- http://mail.python.org/mailman/listinfo/python-list