简体   繁体   中英

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

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 lock, and a 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(message) , and calls condition.notify . Thread A is now scheduled to wake up because of the notify call.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM