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

时间:2019-07-07 06:22:59

标签: 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

为什么不wait()调用只是等待然后在收到通知后获取锁,所以我不明白为什么我要获取锁然后将其释放

1 个答案:

答案 0 :(得分:5)

如果您不持有锁,那么您正在等待的东西可能会在您开始等待之前发生。

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

线程B抓住锁,调用deque.append(message),然后调用condition.notify。现在已安排线程A由于通知调用而唤醒。

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