Python线程等待()队列.join()超时

时间:2013-11-30 23:39:16

标签: python multithreading

在python中,我有多个线程正在运行,我需要主进程等待它们完成,所以我用Queue类.join()方法做到了这一点。但是,我想实现SIGINT,但是它的处理程序不会执行,因为join()阻止它(线程进程至少运行5分钟,因为我有他们在做什么)。所以我修改了Queue的.join()并在wait()中放了一个时间:

class CustomQueue(Queue.Queue):
    #Can not use .join() because it would block any processing
    #for SIGINT untill threads are done. To counter this,
    # wait() is given a time out along with while not kill_received
    #to be checked

    def join(self):
        self.all_tasks_done.acquire()
        try:
            while not kill_received and self.unfinished_tasks:
                self.all_tasks_done.wait(10.0)
        finally:
            self.all_tasks_done.release()

这对我来说非常漂亮和完美。

但我不明白的是等待时间()。例如,我不应该发送SIGINT并让它处理至少10秒。但是,我能在不到10秒的时间内完成。无论秒是什么,SIGINT处理程序函数都能够在不被阻止的情况下处理。为什么是这样?我应该等待至少10秒等待超时并且self.all_tasks_done.release()运行以便SIGINT函数将处理...而不是在wait()超时之前处理SIGINT函数。

1 个答案:

答案 0 :(得分:2)

我们在这里缺少可能很重要的信息:

  1. 哪个版本的Python?
  2. 哪个操作系统?
  3. 这可能很重要,因为将线程与信号混合是一个跨平台的混乱。 CPython 尝试来理解这一切,但在不同的Python版本和操作系统上取得了不同程度的成功。

    无论如何,您的问题的答案可能很简单;-) Queue.all_tasks_donethreading.ConditionCondition实现.wait(timeout)(最终,向下钻取)使用time.sleep()。据记载,

      

    time.sleep(秒)   暂停执行给定的秒数。 ... 实际上   暂停时间可能会少于所要求的,因为任何被抓住   信号将在执行后终止sleep()   信号的捕捉程序。 ...

    默认SIGINT会引发KeyboardInterrupt。因此,如果您没有为SIGINT安装处理程序,SIGINT会提前终止sleep()并提升KeyboardInterrupt。如果您确实安装了SIGINT处理程序,SIGINT仍会提前终止sleep(),但之后会发生什么情况取决于您的处理程序所做的事情。