[Baypiggies] Synchronized in Python

Monte Davidoff davidoff56 at alluvialsw.com
Mon Nov 12 05:33:18 CET 2007


Stephen McInerney and I were talking after the last BayPIGgies meeting 
(Concurrency in Python) and thought it might be of help to post how to 
get the effect of the Java synchronized keyword in Python.  (I arrived a 
little late, so perhaps this was mentioned before I got there.)  This 
post is meant as a quick example, so the explanation is brief and I hope 
not too confusing.  In Java, the synchronized keyword ensures that only 
one thread is executing a method or block at a time.

To synchronize a block of code, you can use the with statement (new in 
Python 2.5) in conjunction with a lock from the threading module in the 
standard library:

     from __future__ import with_statement

     # Allocate a lock
     import threading
     lock = threading.RLock()

How to synchronize a block of code:

     with lock:
         # critical section of code
         ...

If you are not using Python 2.5, you can use try...finally instead of a 
with statement.  The above "with lock" is equivalent to:

     lock.acquire()
     try:
         # critical section of code
         ...
     finally:
         lock.release()

In the above examples, the lock is acquired before the critical section 
of code is entered.  The lock is released when the critical section of 
code is complete, even if the critical section executes a return 
statement or raises an exception.

To easily synchronize a function or method, you can use a decorator:

     def synchronized(L):
         def lock_around(f):
             def locked(*a, **k):
                 with L:
                     return f(*a, **k)
             locked.__name__ = f.__name__
             locked.__doc__ = f.__doc__
             return locked
         return lock_around

(Decorator courtesy of Alex Martelli, 
http://www.aleax.it/Python/osc05_bla_dp.pdf, slide 14.)

How to use the decorator to synchronize a function:

     @synchronized(lock)
     def my_synchronized_function():
         # critical section of code
         ...

How to synchronize a method:

     class C(object):
         @synchronized(lock)
         def my_synchronized_method(self):
             # critical section of code
             ...

When writing multithreaded code, I found these idioms to be quite useful.

Monte


More information about the Baypiggies mailing list