Python如何用信号杀死队列中阻塞的线程?

gbr*_*gbr 6 python queue multithreading

我开始在队列上运行一堆线程,我想在发送SIGINT时按下它们(Ctrl + C).处理这个问题的最佳方法是什么?

targets = Queue.Queue()
threads_num = 10
threads = []

for i in threads_num:
    t = MyThread()
    t.setDaemon(True)
    threads.append(t)
    t.start()

targets.join()
Run Code Online (Sandbox Code Playgroud)

小智 5

如果您不想让其他线程正常关闭,只需在守护进程模式下启动它们,并将队列的连接包装在终结器线程中.

这样,您可以使用join线程的方法 - 它支持超时并且不会阻止异常 - 而不必等待队列的join方法.

换句话说,做这样的事情:

term = Thread(target=someQueueVar.join)
term.daemon = True
term.start()
while (term.isAlive()):
    term.join(3600)
Run Code Online (Sandbox Code Playgroud)

现在,Ctrl + C将终止MainThread,因此Python解释器会强制杀死标记为"守护进程"的所有线程.请注意,这意味着您必须为所有其他线程设置"Thread.daemon",或者通过捕获正确的异常(KeyboardInterrupt或SystemExit)并执行任何需要为其退出的操作来正常关闭它们.

还要注意,您绝对需要传递一个数字term.join(),否则它也会忽略所有异常.但是,您可以选择任意高的数字.


Use*_*ess 4

不是Ctrl+吗C SIGINT

无论如何,您可以为适当的信号安装一个处理程序,并在处理程序中:

  • 设置一个全局标志来指示工作人员退出,并确保他们定期检查它
  • 或者将 10 个关闭令牌放入队列中,并让工作人员在弹出此魔术令牌时退出
  • 或设置一个标志来指示主线程推送这些令牌,确保主线程检查该标志

等等。主要取决于您正在中断的应用程序的结构。