Is there a python lock annotation which has the same effect to a python method as the "synchronized" keyword to java methods?
A lock can be locked using the acquire() method. Once a thread has acquired the lock, all subsequent attempts to acquire the lock are blocked until it is released. The lock can be released using the release() method. Calling the release() method on a lock, in an unlocked state, results in an error.
A mutex is an object enabling threads of execution to protect critical sections of code from reentrancy or to temporarily protect critical data sets from being updated by other threads. The term “mutex” derives from the notion of mutual exclusion.
Acquiring a lock allows a thread to have exclusive access to the data guarded by that lock, forcing other threads to block — as long as those threads are also trying to acquire that same lock. The monitor pattern guards the rep of a datatype with a single lock that is acquired by every method.
The threading module provided with Python includes a simple-to-implement locking mechanism that allows you to synchronize threads. A new lock is created by calling the Lock() method, which returns the new lock. The acquire(blocking) method of the new lock object is used to force threads to run synchronously.
I can assume that no builtin feature exist in python but you can implement it by understanding how it work in Java from this link :
Every Java object created, including every Class loaded, has an associated lock or monitor. Putting code inside a synchronized block makes the compiler append instructions to acquire the lock on the specified object before executing the code, and release it afterwards (either because the code finishes normally or abnormally). Between acquiring the lock and releasing it, a thread is said to "own" the lock. At the point of Thread A wanting to acquire the lock, if Thread B already owns the it, then Thread A must wait for Thread B to release it.
so maybe something like this can work :
synchronized statement in java:
public class Java {
static private int count = 0;
public void increment() {
synchronized (this) {
count++;
}
}
}
became :
import threading
class Java:
cout = 0
lock = threading.RLock()
def increment():
with Java.lock:
Java.cout += 1
and synchronized method in Java:
public class Java {
static private int count = 0;
public synchronized void increment() {
count ++;
}
}
became:
import threading
def synchronized(method):
""" Work with instance method only !!! """
def new_method(self, *arg, **kws):
with self.lock:
return method(self, *arg, **kws)
return new_method
class Java:
count = 0
lock = threading.RLock()
@synchronized
def incremenet(self):
Java.count += 1
Explicit is better than implicit.
N.B: my knowledge in Java is very limited, and it's my first lecture about this Java feature so maybe i miss something (or maybe i miss all the point here :) ), well hope this answer can help someone.
N.B: the lock that i have created is a class variable so threading synchronization happen in class level, if we want to make the synchronization in instance level (only) which i think that how java do it, the code above must change.
I sometimes use a decorator like this:
def synchronized(f):
@functools.wraps(f)
def wrapper(self, *args, **kwargs):
try:
_ = self._lock
except AttributeError:
self._lock = threading.Lock()
with self._lock:
return f(self, *args, **kwargs)
return wrapper
This solution has a race condition when calling the decorated method for the first time, though. The simplest way to avoid this problem is to call one synchronized method when no other threads are running first, or to assign the self._lock
manually in __init__
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With