threading.Condition.wait(timeout)忽略threading.Condition.notify()

时间:2014-06-10 09:29:00

标签: python multithreading python-3.x python-multithreading condition-variable

我有一个使用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。对我来说,这似乎是一种竞争条件,显然如果notifywait同时被调用,则无法识别通知。我认为exitCondition.acquire()exitCondition.release()应该阻止这种情况。问题是为什么条件变量不是线程安全的,我可以做些什么。理想情况下,我想写wait(0),保证不会吞下任何通知。

1 个答案:

答案 0 :(得分:2)

如果在工作线程正在工作时发生对exitCondition.notify的调用(即,在sleep(.1)调用中(或.wait调用以外的任何其他地方),则行为你描述的声音就像我期望的那样。只有在 wait期间发生通知时,True调用才会返回wait

听起来好像这是threading.Event而不是threading.Condition的用例:将threading.Condition替换为threading.Event,替换为notify调用set来调用,并完全删除acquirerelease个调用(在两个线程中)。

也就是说,代码应如下所示:

#!/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()