classification
Title: Add serialized decorator to the threading module
Type: enhancement Stage:
Components: Library (Lib) Versions: Python 3.4
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: jjdominguezm, jyasskin, neologix, pitrou, r.david.murray
Priority: normal Keywords:

Created on 2012-08-13 08:04 by jjdominguezm, last changed 2012-08-24 10:43 by neologix.

Messages (7)
msg168071 - (view) Author: Juan Javier (jjdominguezm) Date: 2012-08-13 08:04
I think it will be useful to have a decorator like this one on the threading module:

def synchronized(func):
    """A decorator to make a function execution synchronized.

    Examples:

    @synchronized
    def foo():
        pass

    class Foo:
        def __init__(self):
            self.__syncdata = None

        @property
        def syncdata(self):
            return self.__syncdata

        @syncdata.setter
        @synchronized
        def syncdata(self, value):
            self.__syncdata = value
    """
    if not hasattr(func, "__lock"):
        func.__lock = threading.Lock()
    def _synchronized(*args, **kwds):
        with func.__lock:
            func(*args, **kwds)
    _synchronized.__doc__ = func.__doc__
    return _synchronized

What do you think?
msg168098 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-13 12:52
Writing such a decorator is pretty trivial to do.  On the other hand, I've done it often enough that I could be convinced it is useful to add.

I think it would be better to have a decorator generator that takes a lock as its argument, however, since an application might well want to use the same lock for sections that it doesn't make sense to decorate, or use an RLock instead of a lock.  If no lock is passed, a default Lock could be created.
msg168099 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2012-08-13 12:54
Oh, I misread your code.

The code I'm working on uses the lock to serialize several different functions, and your decorator wouldn't work for that.
msg168100 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2012-08-13 13:00
I'm not sure how useful that is in practice. Often you want to use the same lock accross several functions or methods.
Also, I think it would be more accurate to call this "serialized" than "synchronized".
msg168178 - (view) Author: Juan Javier (jjdominguezm) Date: 2012-08-14 06:55
Ok, you are right, serialized is the right name. Also, passing the lock to the decorator will the correct option.
msg168179 - (view) Author: Juan Javier (jjdominguezm) Date: 2012-08-14 08:10
What about this?

def serialized(lock):
    def _serialized(func):
        def __serialized(*args, **kwds):
            with lock:
                return func(*args, **kwds)
        __serialized.__doc__ = func.__doc__
        return __serialized
    return _serialized
msg168996 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2012-08-24 10:43
"synchronized" has the merit of reusing Java's denomination, which this decorator intends to mimic, see http://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html

Basically, synchronize works with the object/class (implicit) reentrant lock.
History
Date User Action Args
2012-08-24 10:43:33neologixsetnosy: + neologix
messages: + msg168996
2012-08-17 18:13:33terry.reedysettitle: synchronized decorator for the threading module -> Add serialized decorator to the threading module
2012-08-14 08:10:19jjdominguezmsetmessages: + msg168179
2012-08-14 06:55:11jjdominguezmsetmessages: + msg168178
2012-08-13 13:00:35pitrousetnosy: + jyasskin, pitrou
messages: + msg168100
2012-08-13 12:54:21r.david.murraysetmessages: + msg168099
2012-08-13 12:52:09r.david.murraysetnosy: + r.david.murray
messages: + msg168098
2012-08-13 08:04:28jjdominguezmcreate