带线程的Python程序无法捕获CTRL + C [英] Python program with thread can't catch CTRL+C

查看:348
本文介绍了带线程的Python程序无法捕获CTRL + C的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am writing a python script that needs to run a thread which listens to a network socket.

使用以下代码使用 Ctrl + c 杀死它时遇到了麻烦:

I'm having trouble with killing it using Ctrl+c using the code below:

#!/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 并终止脚本的任何建议.

Appreciate any advise on how to catch Ctrl+c and terminate the script.

推荐答案

问题在于,在执行脱离主线程(返回main()之后)之后,threading模块将暂停,等待其他线程使用锁完成;并且锁不能被信号打断.至少在Python 2.x中就是这种情况.

The issue is that after the execution falls off the main thread (after main() returned), the threading module will pause, waiting for the other threads to finish, using locks; and locks cannot be interrupted with signals. This is the case in Python 2.x at least.

一个简单的解决方法是通过添加一个无限循环来避免掉主线程,该无限循环调用一些休眠的函数,直到某些动作可用为止,例如select.select().如果根本不需要主线程执行任何操作,请使用signal.pause().示例:

One easy fix is to avoid falling off the main thread, by adding an infinite loop that calls some function that sleeps until some action is available, like select.select(). If you don't need the main thread to do anything at all, use signal.pause(). Example:

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

这篇关于带线程的Python程序无法捕获CTRL + C的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆