Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does python require you to acquire a lock before waiting on a condition

Python has a threading Object called Condition which blocks a thread waiting until another thread calls notifiy() or notify_all() on it. Before calling the wait() method however, you must first call acquire() to acquire the internal lock. the wait() method then releases the lock and waits to be notified, after which it will proceed to reacquiring the lock and you can run some code that needed to be thread-safe. My question is why doesn't the Condition object just acquire the lock automatically internally when you call the wait() method:

Python threading documentation

Other methods must be called with the associated lock held. The wait() method releases the lock, and then blocks until another thread awakens it by calling notify() or notify_all(). Once awakened, wait() re-acquires the lock and returns. It is also possible to specify a timeout.

So in this code I acquire the lock, wait method immediately releases it and then after it's notified it acquires it again then i eventually release it.

lock = threading.Lock()
condition = threading.Condition(lock=lock)
...
condition.lock()    # acquire the lock
condition.wait()    #  waiting for another thread to notify me
condition.release() # release the lock

why doesn't the wait() call just wait and then acquire the lock once it has been notified I don't see why I am acquiring the lock that it will then release

like image 450
masonCherry Avatar asked Jul 07 '19 06:07

masonCherry


People also ask

What does lock acquire do in Python?

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.

What is lock acquire?

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.

How do you wait for an event in Python?

Though there are a plethora of ways to make a pause in Python the most prevalent way is to use the wait() function. The wait() method in Python is used to make a running process wait for another function to complete its execution, such as a child process, before having to return to the parent class or event.

What is the method that wakes up all thread waiting for the condition in Python?

notifyAll() method It wakes up all the threads waiting on this condition.


1 Answers

If you weren't holding the lock, the thing you're waiting for could happen before you started waiting for it.

Say you've got a homebrew message queue implemented with a collections.deque, a threading.Lock, and a threading.Condition variable.

Thread A wants to read an item from the queue, so it grabs the lock, checks the deque, and there's no item. Thread A calls condition.wait to wait for another thread to put something in.

Thread B grabs the lock, calls deque.append, and calls condition.notify. Thread A is now scheduled to wake up because of the condition.notify call.

Imagine if thread A could release the lock before calling condition.wait. In that case, thread B might append its item and call condition.notify before thread A starts waiting. Thread A would never wake up.

like image 166
user2357112 supports Monica Avatar answered Sep 30 '22 13:09

user2357112 supports Monica