带线程的Python程序无法捕获CTRL+C

2024-05-12 21:42:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在编写一个python脚本,它需要运行一个监听网络套接字的线程。

我很难用下面的代码通过Ctrl+c杀死它:

#!/usr/bin/python

import signal, sys, threading

THREADS = []

def handler(signal, frame):
    global THREADS
    print "Ctrl-C.... Exiting"
    for t in THREADS:
        t.alive = False
    sys.exit(0)

class thread(threading.Thread):
    def __init__(self):
        self.alive = True
        threading.Thread.__init__(self)


    def run(self):
        while self.alive:
            # do something
            pass

def main():
    global THREADS
    t = thread()
    t.start()
    THREADS.append(t)

if __name__ == '__main__':
    signal.signal(signal.SIGINT, handler)
    main()

感谢任何有关如何捕获Ctrl+c并终止脚本的建议。


Tags: self脚本signalinitmaindefsysglobal
2条回答

问题是,在执行从主线程上脱落(在返回main()之后,threading模块将暂停,等待其他线程使用锁完成;锁不能被信号中断。至少在Python2.x中是这样的。

一个简单的解决方法是通过添加一个无限循环来避免脱离主线程,该循环调用一些函数,这些函数在某些操作可用之前一直处于休眠状态,比如select.select()。如果根本不需要主线程执行任何操作,请使用signal.pause()。示例:

if __name__ == '__main__':
    signal.signal(signal.SIGINT, handler)
    main()
    while True:           # added
        signal.pause()    # added

这是因为信号只能由主线程捕获。主线程在很久以前就结束了他的生命(应用程序正在等待您的线程完成)。尝试添加

while True: 
    sleep(1)

在你的main()结尾(当然还有最上面的from time import sleep)。

或者正如凯文所说:

for t in THREADS:
    t.join(1) # join with timeout. Without timeout signal cannot be caught.

相关问题 更多 >