问题描述
此问题与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()
...
解决方法
我相信您确实不需要使用条件。看来,简单的Lock
就可以完成您的任务。您实际上并没有验证是否满足某些条件,也没有使用条件的特殊方法wait()
。
也就是说,对于您提供的代码,您的主线程似乎太“快速”,并在另一个线程获得机会之前重新获取了锁。 这是您的代码的稍作修改的版本,在该版本中,主线程稍稍等待了一下,给另一个线程一个机会,它成功获取了锁定并继续。
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()
种族条件很有趣:)