首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Threading.Condition.wait(超时)忽略threading.Condition.notify()

Threading.Condition.wait(超时)忽略threading.Condition.notify()
EN

Stack Overflow用户
提问于 2014-06-10 09:29:00
回答 1查看 2.3K关注 0票数 3

我有一个使用2个线程的应用程序。我希望能够通过等待条件变量exitCondition来关闭两个线程。我使用python3.3,它与python2.7不同,它使threading.Condition.wait()在通知条件时返回True,在超时时返回False

代码语言:javascript
复制
#!/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。在我看来,这是一种竞争条件,显然,如果notifywait同时被调用,则通知是不被识别的。我的印象是,exitCondition.acquire()exitCondition.release()应该防止这种情况发生。问题是为什么条件变量不是线程安全的,以及我能做些什么。理想情况下,我想编写wait(0),保证不会吞食任何通知。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-06-10 09:57:35

如果对exitCondition.notify的调用发生在工作线程进行工作时(即,在sleep(.1)调用中(或在.wait调用以外的任何其他地方),那么您描述的行为听起来与我所期望的完全一样。只有在通知发生在wait期间时,True调用才返回wait

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

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

代码语言:javascript
复制
#!/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调用来替换它,以查看是否设置了退出条件:

代码语言:javascript
复制
#!/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()
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24137480

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档