为什么python在条件等待之前要求您获取锁

MrB*_*197 7 python multithreading python-internals

Python有一个称为的线程对象Condition,它阻塞一个线程,直到另一个线程调用notifiy()notify_all()在其上等待。wait()但是,在调用该方法之前,必须先调用acquire()以获取内部锁。wait()然后该方法释放锁并等待通知,此后它将继续重新获取锁,并且您可以运行一些需要线程安全的代码。我的问题是,为什么Condition调用该wait()方法时对象不只是在内部自动获取锁:

Python线程文档

必须使用关联的锁来调用其他方法。该wait()方法释放该锁,然后阻塞直到另一个线程通过调用notify()或唤醒它notify_all()。唤醒后,wait()重新获取锁并返回。也可以指定超时。

因此,在此代码中,我获取了锁,wait方法立即释放它,然后在通知它再次获取它之后,我最终释放了它。

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

Run Code Online (Sandbox Code Playgroud)

为什么wait()呼叫不只是等待,然后在收到通知后立即获取锁,所以我看不到为什么要获取然后释放的锁

use*_*ica 5

如果您没有握住锁,那么正在等待的事情可能会您开始等待之前发生。

假设您已经实现了一个带有collections.deque,锁和条件变量的自制消息队列。线程A想要从队列中读取项目,因此它抓住了锁,检查了双端队列,并且没有项目。线程A调用condition.wait以等待另一个线程放入某些东西。

线程B获取锁,调用deque.append(message)和调用condition.notify。现在已安排线程A由于notify调用而唤醒。

想象一下,线程A是否可以在调用之前释放锁wait。在这种情况下,线程B可能会condition.notify在线程A开始等待之前附加其消息并调用。线程A永远不会唤醒。

  • @flakes:如果线程 B 在线程 A 获取锁之前放入一条消息,那么线程 A 将看到该消息而不等待。当然,如果你搞砸了事情并犯了一个错误,仍然有可能得到无限的等待。 (2认同)