如何在线程python程序中捕获SIGINT?

时间:2010-10-04 09:15:32

标签: python multithreading signals sigint

使用线程模块和Thread()类时,无法捕获SIGINT(控制台中的Ctrl + C)。

为什么以及我该怎么办?

简单的测试程序:

#!/usr/bin/env python

import threading

def test(suffix):
    while True:
        print "test", suffix

def main():
    for i in (1, 2, 3, 4, 5):
        threading.Thread(target=test, args=(i, )).start()

if __name__ == "__main__":
    main()

尝试按Ctrl-C - 没有任何反应。

2 个答案:

答案 0 :(得分:9)

线程和信号不会混合。在Python中,这种情况比外部情况更多:信号只能传递到一个线程(主线程);其他线程不会收到消息。除了主线程之外,你无法中断线程。他们不受你的控制。

您可以在这里做的唯一事情是使用queue模块在​​主线程和您启动的任何线程之间引入通信通道。然后,您可以向线程发送消息,并在看到消息时终止(或执行其他任何操作)。

或者,它通常是一个非常好的选择,是不使用线程。然而,使用什么在很大程度上取决于你想要实现的目标。

答案 1 :(得分:-1)

基本上,您可以通过在工作期间读取队列来检查父母是否发出了信号。如果父接收到一个SIGINT,那么它会在整个队列中发出一个信号(在这种情况下是任何东西),然后孩子们完成他们的工作并退出......

def fun(arg1, thread_no, queue):
   while True:
    WpORK...
    if queue.empty() is False or errors == 0:
     print('thread ', thread_no, ' exiting...')
     with open('output_%i' % thread_no, 'w') as f:
      for line in lines: f.write(line)
     exit()

threads = []
for i, item in enumerate(items):
 threads.append( dict() )
 q = queue.Queue()
 threads[i]['queue'] = q
 threads[i]['thread'] = threading.Thread(target=fun, args=(arg1, i, q))
 threads[i]['thread'].start()
try:
 time.sleep(10000)
except:
 for thread in threads:
  thread['queue'].put('TERMINATING')