myo*_*oan 3 python multithreading sigint
我无法理解为什么我的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()
Run Code Online (Sandbox Code Playgroud)
要清理这段代码,我更喜欢尝试/除了join()并在异常情况下关闭所有线程,这会有用吗?
python中多线程的一个问题是join()或多或少地禁用了信号.
这是因为信号只能传递给主线程,但主线程已经忙于执行,join()并且连接不可中断.
您可以从signal模块的文档中推断出这一点
如果在同一程序中使用信号和线程,则必须小心.在同时使用信号和线程时要记住的基本要点是:始终在执行的主线程中执行signal()操作.任何线程都可以执行alarm(),getsignal(),pause(),setitimer()或getitimer(); 只有主线程可以设置一个新的信号处理程序,主线程将是唯一一个接收信号的线程(这是由Python信号模块强制执行的,即使底层线程实现支持向各个线程发送信号).这意味着信号不能用作线程间通信的手段.改用锁.
您可以通过忙于循环连接操作来解决它:
for t in threads:
while t.isAlive():
t.join(timeout=1)
Run Code Online (Sandbox Code Playgroud)
但是,这没有效率:
使用超时调用join()的解决方法有一个缺点:Python的线程等待例程在给定任何超时时每秒轮询20次.所有这些轮询都意味着在笔记本电脑空闲的情况下会有大量的CPU中断/唤醒,并且会更快耗尽电池电量.
这里提供了更多细节:
可以在此处找到有关此问题的Bug报告以及对基础问题的讨论:
https://bugs.python.org/issue1167930
https://bugs.python.org/issue1171023