python - 为什么python要求您在等待条件之前获取锁
问题描述
Python 有一个调用的线程对象Condition
,它阻塞一个线程,直到另一个线程调用notifiy()
或notify_all()
在它上面。但是,在调用该wait()
方法之前,您必须先调用acquire()
以获取内部锁。然后该wait()
方法释放锁并等待通知,之后它将继续重新获取锁,您可以运行一些需要线程安全的代码。我的问题是,当您调用该方法时,为什么Condition
对象不只是在内部自动获取锁:wait()
Python 线程文档
必须在持有相关锁的情况下调用其他方法。该
wait()
方法释放锁,然后阻塞,直到另一个线程通过调用notify()
or唤醒它notify_all()
。一旦唤醒,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()
调用不只是等待然后在收到通知后获取锁我不明白为什么我要获取它将释放的锁
解决方案
如果您没有持有锁,那么您正在等待的事情可能会在您开始等待之前发生。
假设您有一个用 a collections.deque
、 athreading.Lock
和 athreading.Condition
变量实现的自制消息队列。
线程 A 想从队列中读取一个项目,所以它抓取lock
,检查deque
,并且没有项目。线程 A 调用condition.wait
以等待另一个线程放入某些东西。
线程 B 抓取lock
、 调用deque.append
和 调用condition.notify
。condition.notify
由于调用,线程 A 现在计划唤醒。
想象一下,如果线程 A 可以释放lock
调用之前的condition.wait
. condition.notify
在这种情况下,线程 B 可能会在线程 A 开始等待之前附加其项目并调用。线程 A 永远不会醒来。
推荐阅读
- powershell - VS 2015 MSDeployPublish 未执行
- python - 如何在使用 python 绘制 netCDF 文件中的任何变量之前网格化网格
- java - 错误注入:org.jboss.as.plugin.deployment.Deploy
- ios - 字典的客户端过滤以获得唯一值
- php - CSV 数据到 array_map 和 str_getcsv 使用分隔符
- python - 为 os.environ 引发 EnvironmentError 是否合适?
- java - Android 架构蓝图“todo‑mvp‑dagger”,@Provides for TasksRepository 在哪里?
- nodes - 在 .ecore_diagram (GMF) 中为 Eclasses 和 EReferenzes 着色
- python - 如何使用 Python 驱动程序获取 Cassandra 集群的名称?
- android - FCM 推送通知问题:当我点击通知时,每次我从意图获得 getExtras() 时都是空的。(应用程序在后台)