Synchronization mixin in Python anyone?

Chris Liechti cliechti at gmx.net
Fri May 3 20:44:55 EDT 2002


Gustavo Cordova <gcordova at hebmex.com> wrote in 
news:mailman.1020461587.9261.python-list at python.org:
> Hmmm... interesting problem. I've been playing with a function
> synchronization class lately, just toying with the idea. I don't
> know if anybody wants it, but here's the basic skeleton:
> 
> ### SynchronizedCall
> import thread
> 
> class SynchronizedCall:
>    def __init__(self, function, *args, **kw):
>       self._lock = thread.Lock()
>       self._args = args
>       self._kw = kw
>       self._function = function
> 
>   def __call__(self, *args, **kw):
>       self._lock.acquire()
>       try:
>          args = self._args + args
>          kw.update(self._kw)
>          result = self._function(*args, **kw)
> 
>       ## In case of an exception, release lock first.
>       except:
>          self._lock.release()
>          raise
> 
>       self._lock.release()
>       return result
> 
> ## THE END

the "except" is wrong placed here - that's what "try: finally:" is for:

       try:
          args = self._args + args
          kw.update(self._kw)
          return = self._function(*args, **kw)
       finally:       
          self._lock.release()

> Really quite simple.

well, you're mixing locking and currying in one wrapper. i would prefer to 
have them separately.
 
> The thing that discouraged me from trying to do this with
> instance methods, is that it becomes a bit complicated if
> someone takes a reference to a method, like I do commonly:
> 
> ## Example
> 
> rex = sre.compile(r"really big and complicated", sre.S|sre.I)
> 
> find_everything = rex.findall
> 
> while ... :
>    ...
>    things = find_everything(string)
>    ...
> 
> ## End example
> 
> So, how would I protect calls to rex.findall() when they're
> done through find_everything() ?

by replacing rex.findall with the wrapped method.
something like that:
rex.__class__.findall = SynchronizedCall(rex.__class__.findall)
(note that this has side effects on all instaces of the "Regular Expression 
Object" and therefore should be considered evil)


with user defined classes this at least looks easier:

class A:
    	def f():
    	    	print "hello"
    	f = SynchronizedCall(f)

the problem here, like above, is that it has an effect on all instaces of 
A, because there is only _one_ lock for all instances. not realy what you 
want...

the SynchronizedCall wrapper might be too simple for OO. i think it makes 
more sense when one method can lock out another on the same instance, like 
"synchronized" in Java (e.g. get and set methods for an attribute can not 
be called at the same time). maybe it is that what the OP wanted with his 
mix-in.

chris

-- 
Chris <cliechti at gmx.net>




More information about the Python-list mailing list