线程.条件.等待(超时)忽略线程.条件.通知()

2024-10-02 12:30:55 发布

您现在位置:Python中文网/ 问答频道 /正文

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

#!/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是“未对齐”(例如.25和.1),程序将终止。如果sleep是“对齐的”(例如.2和.1),inThread将无限期地运行false永远打印。对我来说,这看起来像是一个竞争条件,显然如果notifywait同时被调用,则通知无法被识别。我的印象是exitCondition.acquire()和{}应该可以阻止这种情况。问题是为什么条件变量不是线程安全的,我能做些什么。理想情况下,我希望写wait(0),并保证不会吞下任何通知。在


Tags: importreleasesleepcondition条件线程printthreading
1条回答
网友
1楼 · 发布于 2024-10-02 12:30:55

如果对exitCondition.notify的调用发生在工作线程执行工作时(即在sleep(.1)调用中(或在{}调用之外的任何地方),那么您描述的行为听起来就像我所期望的那样。只有在通知发生在wait期间时,wait调用才会返回True。在

在我看来,这似乎是一个threading.Event而不是threading.Condition:将threading.Condition替换为threading.Event,将notify调用替换为set调用,并删除acquire和{}调用(在两个线程中)。在

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

#!/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调用来替换它,以查看是否已经设置了退出条件:

^{pr2}$

相关问题 更多 >

    热门问题