Python 未捕获 SIGINT

Python SIGINT not caught

我无法理解为什么我的 SIGINT 从未被下面的代码捕获。

#!/usr/bin/env python
from threading import Thread
from time import sleep
import signal

class MyThread(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.running = True

    def stop(self):
        self.running = False

    def run(self):
        while self.running:
            for i in range(500):
                col = i**i
                print col
                sleep(0.01)

global threads
threads = []

for w in range(150):
    threads.append(MyThread())

def stop(s, f):
    for t in threads:
        t.stop()

signal.signal(signal.SIGINT, stop)

for t in threads:
    t.start()

for t in threads:
    t.join()

要清理此代码,我更愿意 try/except join() 并在出现异常时关闭所有线程,这样行得通吗?

python 中多线程的一个问题是 join() 或多或少地禁用了信号。

这是因为信号只能传递给主线程,但是主线程已经忙于执行join(),join是不可中断的。

您可以从 signal 模块的文档中推断出这一点

Some care must be taken if both signals and threads are used in the same program. The fundamental thing to remember in using signals and threads simultaneously is: always perform signal() operations in the main thread of execution. Any thread can perform an alarm(), getsignal(), pause(), setitimer() or getitimer(); only the main thread can set a new signal handler, and the main thread will be the only one to receive signals (this is enforced by the Python signal module, even if the underlying thread implementation supports sending signals to individual threads). This means that signals can’t be used as a means of inter-thread communication. Use locks instead.

您可以通过忙循环连接操作来解决它:

for t in threads:
    while t.isAlive():
        t.join(timeout=1)

然而,这 none 有效:

The workaround of calling join() with a timeout has a drawback: Python's threading wait routine polls 20 times a second when given any timeout. All this polling can mean lots of CPU interrupts/wakeups on an otherwise idle laptop and drain the battery faster.

此处提供了更多详细信息:

Python program with thread can't catch CTRL+C

可以在此处找到有关此问题的错误报告以及对基本问题的讨论:

https://bugs.python.org/issue1167930

https://bugs.python.org/issue1171023