Is there a way to protect a piece of critical code?

robert no-spam at no-spam-no-spam.invalid
Fri Jan 12 06:29:41 EST 2007


Hendrik van Rooyen wrote:
> "robert" <no-spam at no-spam-no-spam.invalid> 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



More information about the Python-list mailing list