我有一个使用2个线程的应用程序。我希望能够通过等待条件变量exitCondition来关闭两个线程。我使用python3.3,它与python2.7不同,它使threading.Condition.wait()在通知条件时返回True,在超时时返回False。
#!/usr/bin/python
import threading
from time import sleep
exitCondition = threading.Condition()
def inputActivity():
while True:
exitCondition.acquire()
exitConditionReached = exitCondition.wait(.1) #<-critical
print(exitConditionReached)
exitCondition.release()
if exitConditionReached: #exitCondition reached -> shutdown
return
else: #exitCondition not reached -> do work
sleep(.1)
inThread = threading.Thread(target = inputActivity)
inThread.start()
sleep(.2) #<-critical
exitCondition.acquire()
exitCondition.notify()
print("exitCondition notified")
exitCondition.release()
inThread.join()在第10行和第21行中有2行带有#<-critical注释。如果sleeps“不对齐”(例如,.25和.1),程序将终止。如果sleeps“对齐”(例如,.2和.1),则inThread将永远无限期地运行打印false。在我看来,这是一种竞争条件,显然,如果notify与wait同时被调用,则通知是不被识别的。我的印象是,exitCondition.acquire()和exitCondition.release()应该防止这种情况发生。问题是为什么条件变量不是线程安全的,以及我能做些什么。理想情况下,我想编写wait(0),保证不会吞食任何通知。
发布于 2014-06-10 09:57:35
如果对exitCondition.notify的调用发生在工作线程进行工作时(即,在sleep(.1)调用中(或在.wait调用以外的任何其他地方),那么您描述的行为听起来与我所期望的完全一样。只有在通知发生在wait期间时,True调用才返回wait。
在我看来,这似乎是threading.Event而不是threading.Condition的用例:将threading.Condition替换为threading.Event,将notify调用替换为set调用,并完全删除acquire和release调用(在这两个线程中)。
也就是说,代码应该如下所示:
#!/usr/bin/python
import threading
from time import sleep
exitCondition = threading.Event()
def inputActivity():
while True:
exitConditionReached = exitCondition.wait(.1) #<-critical
print(exitConditionReached)
if exitConditionReached: #exitCondition reached -> shutdown
return
else: #exitCondition not reached -> do work
sleep(.1)
inThread = threading.Thread(target = inputActivity)
inThread.start()
sleep(.2) #<-critical
exitCondition.set()
print("exitCondition set")
inThread.join()一旦完成了这一步,就不需要第一个.wait了:您可以用一个直接的is_set调用来替换它,以查看是否设置了退出条件:
#!/usr/bin/python
import threading
from time import sleep
exitCondition = threading.Event()
def inputActivity():
while True:
if exitCondition.is_set(): #exitCondition reached -> shutdown
return
else: #exitCondition not reached -> do work
sleep(.1)
inThread = threading.Thread(target = inputActivity)
inThread.start()
sleep(.2) #<-critical
exitCondition.set()
print("exitCondition set")
inThread.join()https://stackoverflow.com/questions/24137480
复制相似问题