[英]Ctrl+c not stopping a Thread in Windows + python3.7
I'm trying this simple thread with a while loop inside.我正在尝试这个简单的线程,里面有一个 while 循环。 When I'm inside the while loop, Ctrl+C has no effect in stopping my program.
当我在 while 循环中时, Ctrl+C 对停止我的程序无效。 Once I go do something else after the while loop, the script stops as intended.
一旦我在 while 循环之后做其他事情,脚本就会按预期停止。 What can I do so my script can be gracefully killed both while being in the while loop and after?
我该怎么做才能在 while 循环中和之后优雅地终止我的脚本? ( Edit: This seems to be a problem exclusive to Windows, iOS and Ubuntu seem to do what I want)
(编辑:这似乎是 Windows 独有的问题,iOS 和 Ubuntu 似乎可以做我想做的事)
import time, threading
class MainClass(threading.Thread):
def __init__(self):
super().__init__()
def run(self):
while True:
time.sleep(1)
print("Looping")
# Script entry point
if __name__ == '__main__':
a = MainClass()
a.daemon = True
a.start()
a.join()
This is a known issue, explained in Issue 35935 .这是一个已知问题,在问题 35935 中进行了解释。
A way to solve it is to use an event, which is passed into the thread class, which waits for the SIGINT to be triggered.一种解决方法是使用一个事件,该事件被传递到线程类中,等待 SIGINT 被触发。 As I understand, a way to overcome the fact that the main thread is blocking the event signal is to revert to the default kernel behaviour of SIGINT using
signal.signal(signal.SIGINT, signal.SIG_DFL)
, (solution pointed out by the issue OP), and the meaning of SIG_DFL is explained fe here .据我了解,克服主线程阻塞事件信号这一事实的方法是使用
signal.signal(signal.SIGINT, signal.SIG_DFL)
恢复到 SIGINT 的默认内核行为,(问题指出的解决方案OP), SIG_DFL 的含义解释为 fe here 。 As to why this has to be the case is beyond the scope of my knowledge.至于为什么必须如此,超出了我的知识范围。
This is by no means a perfect solution, but works on Windows using Python 3.8+.这绝不是一个完美的解决方案,但可以在使用 Python 3.8+ 的 Windows 上运行。
Implementation:执行:
import time, threading
import signal
class MainClass(threading.Thread):
def __init__(self,event):
super().__init__()
self.event = event
def run(self):
while not event.is_set():
time.sleep(1)
print("Looping")
# Script entry point
if __name__ == '__main__':
try:
event = threading.Event()
a = MainClass(event)
a.daemon=True
a.start()
signal.signal(signal.SIGINT, signal.SIG_DFL)
event.wait()
except KeyboardInterrupt:
event.set()
sys.exit(1)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.