我正在使用以下脚本测试Python线程:
import threading
class FirstThread (threading.Thread):
def run (self):
while True:
print 'first'
class SecondThread (threading.Thread):
def run (self):
while True:
print 'second'
FirstThread().start()
SecondThread().start()
这是在Kubuntu 11.10上的Python 2.7中运行的。 Ctrl + C 不会杀死它。我也尝试为系统信号添加处理程序,但这没有帮助:
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
为了杀死进程,我在使用 Ctrl + Z 将程序发送到后台后通过PID将其杀死,这不会被忽略。为什么 Ctrl + C 被如此持久地忽略?我该如何解决这个问题?
答案 0 :(得分:165)
Ctrl + C 终止主线程,但由于您的线程未处于守护进程模式,它们会继续运行,并使进程保持活动状态。我们可以让它们成为守护进程:
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
但是还有另一个问题 - 一旦主线程启动了你的线程,就没有别的办法了。所以它退出,线程立即被销毁。所以让我们保持主线程的活着:
import time
while True:
time.sleep(1)
现在它将保持打印“第一个”和“第二个”,直到你点击 Ctrl + C 。
编辑:正如评论者指出的那样,守护程序线程可能没有机会清理临时文件之类的东西。如果需要,请抓住主线程上的KeyboardInterrupt
并让它协调清理和关闭。但在许多情况下,让守护程序线程突然死亡可能已经足够了。
答案 1 :(得分:8)
KeyboardInterrupt和信号只能由进程看到(即主线程)......看看Ctrl-c i.e. KeyboardInterrupt to kill threads in python
答案 2 :(得分:2)
我认为最好在您希望线程死亡时在线程上调用join()。我对您的代码采取了一些自由行动,以使循环结束(您也可以在其中添加所需的任何清理需求)。每次通过都会检查变量die是否为真,当它为True时,程序将退出。
import threading
import time
class MyThread (threading.Thread):
die = False
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run (self):
while not self.die:
time.sleep(1)
print (self.name)
def join(self):
self.die = True
super().join()
if __name__ == '__main__':
f = MyThread('first')
f.start()
s = MyThread('second')
s.start()
try:
while True:
time.sleep(2)
except KeyboardInterrupt:
f.join()
s.join()
答案 3 :(得分:1)
@Thomas K的答案的改进版本:
is_any_thread_alive()
,该功能可以自动终止main()
。示例代码:
import threading
def job1():
...
def job2():
...
def is_any_thread_alive(threads):
return True in [t.is_alive() for t in threads]
if __name__ == "__main__":
...
t1 = threading.Thread(target=job1,daemon=True)
t2 = threading.Thread(target=job2,daemon=True)
t1.start()
t2.start()
while is_any_thread_alive([t1,t2]):
time.sleep(0)
答案 4 :(得分:0)
要注意一个简单的“问题”,您确定 CAPS LOCK 没有打开吗?
我在 Pi4 上的 Thonny IDE 中运行 Python 脚本。启用 CAPS LOCK 后,Ctrl+Shift+C 被传递到键盘缓冲区,而不是 Ctrl +C.