Reputation: 974
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:
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 callingnotify()
ornotify_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
Upvotes: 12
Views: 3841
Reputation: 282035
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.
Upvotes: 9