在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函数。
答案 0 :(得分:2)
我们在这里缺少可能很重要的信息:
这可能很重要,因为将线程与信号混合是一个跨平台的混乱。 CPython 尝试来理解这一切,但在不同的Python版本和操作系统上取得了不同程度的成功。
无论如何,您的问题的答案可能很简单;-) Queue.all_tasks_done
是threading.Condition
,Condition
实现.wait(timeout)
(最终,向下钻取)使用time.sleep()
。据记载,
time.sleep(秒) 暂停执行给定的秒数。 ... 实际上 暂停时间可能会少于所要求的,因为任何被抓住 信号将在执行后终止sleep() 信号的捕捉程序。 ...
默认SIGINT
会引发KeyboardInterrupt
。因此,如果您没有为SIGINT
安装处理程序,SIGINT
会提前终止sleep()
并提升KeyboardInterrupt
。如果您确实安装了SIGINT
处理程序,SIGINT
仍会提前终止sleep()
,但之后会发生什么情况取决于您的处理程序所做的事情。