我有一个使用2个线程的应用程序。我希望能够通过等待条件变量exitCondition
来关闭两个线程。我使用的是python 3.3,与python 2.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
条评论。如果sleep
是&#34;未对齐&#34; (例如.25和.1)程序将终止。如果sleep
是&#34;对齐&#34; (例如.2和.1)inThread
将永久无限期地打印false
。对我来说,这似乎是一种竞争条件,显然如果notify
与wait
同时被调用,则无法识别通知。我认为exitCondition.acquire()
和exitCondition.release()
应该阻止这种情况。问题是为什么条件变量不是线程安全的,我可以做些什么。理想情况下,我想写wait(0)
,保证不会吞下任何通知。
答案 0 :(得分:2)
如果在工作线程正在工作时发生对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()