python - 为什么通知/释放 Condition 对象时我的线程没有启动备份?
问题描述
这个问题与 Python 3.6 有关。
我有一段代码运行线程库中的一个线程,以及程序的主线程。两个线程都访问一个不是线程安全的对象,所以我让它们在Condition
使用对象之前锁定一个对象。我生成的线程只需要每 5 分钟访问/更新一次该对象,因此循环中有一个 5 分钟的睡眠计时器。
目前,主线程永远不会获得锁。当第二个线程释放Condition
并开始等待sleep()
调用时,主线程永远不会唤醒/获取锁。就好像主线程已经死了一样。
class Loader:
def __init__(self, q):
...
self.queryLock = threading.Condition()
...
thread = Thread(target=self.threadfunc, daemon=True)
thread.start()
...
self.run()
def threadfunc(self):
...
while True:
self.queryLock.acquire()
[critical section #1]
self.queryLock.notify()
self.queryLock.release()
sleep(300)
def run(self):
...
while True:
...
self.queryLock.acquire()
[critical section #2]
self.queryLock.notify()
self.queryLock.release()
...
解决方案
I believe you don't really need to use a Condition. It appears that a simple Lock
would get the job done in your case. You don't actually verify that some condition is met and you don't use the Condition's special method wait()
.
That being said, regarding the code you provided, it seems that your main thread is too "quick", and re-acquires the lock before the other thread gets a chance. Here is a slightly modified version of your code in which the main thread is waiting a bit, giving the other thread a chance, and it successfully acquires the lock and continue.
class Loader:
def __init__(self):
self.queryLock = threading.Condition()
thread = Thread(target=self.threadfunc, daemon=True)
thread.start()
self.run()
def threadfunc(self):
while True:
self.queryLock.acquire()
print("critical section 1")
time.sleep(1)
self.queryLock.notify()
self.queryLock.release()
time.sleep(5)
def run(self):
while True:
self.queryLock.acquire()
print("critical section 2")
time.sleep(2)
self.queryLock.notify()
self.queryLock.release()
print("main is waiting a bit")
time.sleep(1)
Loader()
Race conditions are fun :)
推荐阅读
- ansible - 如何使用公共 ssh 密钥运行 Ansible Playbook
- ios - ADYEN 3.1.2(插入方法)iOS
- html - Angular:在资产文件夹发生更改时防止自动重新编译
- c - 将 SDL 库静态包含到 makefile 中
- java - 通过文件浏览器选择文件后,如何在 onActivityResult() 中使用 getContentResolver().query() 获取文件路径
- date - 我们需要在数据阶段转换中使用哪个函数来获取当月的 DATE
- google-cloud-platform - 在 Google Cloud 上欧洲和印度之间的延迟很大
- android - 如何在自定义视图 Android 中使用数据绑定
- javascript - 如何使用 VSCode 关闭特定文件的标记化
- java - 遇到错误 IllegalArgumentException:向容器添加窗口