1

I have a python 3 class.

I want to synchronize all methods, only one method can be execute at same time, even works in multi thread.

What is the best way to implement?

@synchronized
class Library(object):

    def __init__(self):
        pass

    def method1(self):
        pass

    def method2(self):
        pass
CodingMan
  • 13
  • 2
  • 1
    I found an answer in another place, maybe it can solve your problem:https://stackoverflow.com/questions/39145796/locking-a-method-in-python – Luna Apr 29 '19 at 03:45

1 Answers1

6

You can write a decorator that locks decorated methods with a given lock.

from functools import wraps
from threading import RLock

def synchronized():
    lock = RLock()
    def wrapper(f):
        @wraps(f)
        def inner_wrapper(*args, **kwargs):
            with lock:
                return f(*args, **kwargs)
        return inner_wrapper
    return wrapper

synchronizer = synchronized()

class Library:
    @synchronizer
    def __init__(self):
        pass

    @synchronizer
    def method1(self):
        pass

    @synchronizer
    def method2(self):
        pass

However, this requires you to decorate each method. Here I wrote a mixin with __init_subclass__ that does that automatically.

class Synchronized:
    def __init_subclass__(cls, **kwargs):
        synchronizer = synchronized()
        for name in cls.__dict__:
            attr = getattr(cls, name)
            if callable(attr):
                setattr(cls, name, synchronized(attr))

Notice I used a RLock instead of a Lock. A RLock, or reentrant lock, allows the lock to be acquired multiple times by the same thread. This allows methods to call one another in the same thread.

Usage

class Library(Synchronized):
    def __init__(self):
        pass

    def method1(self):
        pass

    def method2(self):
        pass 
Olivier Melançon
  • 21,584
  • 4
  • 41
  • 73