如何知道threading.Condition.wait(timeout)是否已超时或已被通知?

时间:2015-04-29 07:53:13

标签: python multithreading python-multithreading

我正在开发一个带有一些线程的应用程序,每个线程运行一个带有时间睡眠的无限循环。我想要的是在主要完成后完成所有线程,这里是一个例子:

def main():

    display_res_stop = threading.Condition()
    display_result_t = threading.Thread(target=sample_t, args=(display_res_stop, ))
    display_result_t.start()

    time.sleep(4)

    display_res_stop.acquire()
    display_res_stop.notify()
    display_res_stop.release()


def sample_t(stop_cond):
    stop_cond.acquire()

    while True:
        print 5
        c = stop_cond.wait(10)

    stop_cond.release()

if __name__ == '__main__':
    main()

此解决方案的问题是我不知道condition.wait是否已完成,因为超时或因为已通知。在第二种情况下,while循环应该完成。

起初我正在做一个time.sleep(t)并使用线程事件但是应用程序必须等到所有线程都已经过去。

我正在考虑使用threading.Condition和Event的混合解决方案,但我不知道它是否是最好的事情(条件为'睡眠'和事件要替换为True)。

2 个答案:

答案 0 :(得分:2)

毕竟这很简单,我只是专注于错误的事情:我只需要一个可以用事件停止的睡眠,这就是Event.wait(t)所做的事情。那么问题就可以通过事件来解决。

import threading
import time

def sample_thread(stop_ev):
    while not stop_ev.is_set():
        print 'Thread iteration'
        stop_ev.wait(0.1)

def main():
    stop_ev = threading.Event()
    sample_t = threading.Thread(target=sample_thread, args=(stop_ev, ))
    sample_t.start()

    # Other stuff here, sleep is just dummy
    time.sleep(14)

    stop_ev.set()

    print 'End reached.'

if __name__ == '__main__':
    main()

答案 1 :(得分:1)

执行此操作的简单方法是使用Python 3.2或更高版本,或将当前threading的后端移植到3.1 / 2.7 /等。来自PyPI,或者只是从3.4's source复制该方法的代码。

正如Condition.wait的文档解释:

  

返回值为True,除非给定的超时已到期,在这种情况下它是False

     

在版本3.2中更改:以前,该方法始终返回None

作为旁注,我不确定你在这里需要Condition;你没有检查循环中的标志,或做任何其他应该易受竞争条件影响的标志,你只是等着收到通知。这意味着,只要你不需要魔法自动重置,Event应该没问题。 Event.wait自2.7 / 3.1 +以来已经True / False返回,而不是3.2 +。