【发布时间】:2020-07-05 19:11:43
【问题描述】:
运行以下最小化且可重现的代码示例,python(例如 3.7.3 和 3.8.3)将在第一个 Ctrl+C 时发出如下消息被按下,而不是终止程序。
Traceback (most recent call last):
File "main.py", line 44, in <module>
Main()
File "main.py", line 41, in __init__
self.interaction_manager.join()
File "/home/user/anaconda3/lib/python3.7/threading.py", line 1032, in join
self._wait_for_tstate_lock()
File "/home/user/anaconda3/lib/python3.7/threading.py", line 1048, in _wait_for_tstate_lock
elif lock.acquire(block, timeout):
KeyboardInterrupt
只有在此之后再次按下 Ctrl+C 时,程序才会终止。
这种设计背后的基本原理是什么?避免需要多个 Ctrl+C 或底层信号的优雅方法是什么?
代码如下:
from threading import Thread
from queue import Queue, Empty
def get_event(queue: Queue, block=True, timeout=None):
""" just a convenience wrapper for avoiding try-except clutter in code """
try:
element = queue.get(block, timeout)
except Empty:
element = Empty
return element
class InteractionManager(Thread):
def __init__(self):
super().__init__()
self.queue = Queue()
def run(self):
while True:
event = get_event(self.queue, block=True, timeout=0.1)
class Main(object):
def __init__(self):
# kick off the user interaction
self.interaction_manager = InteractionManager()
self.interaction_manager.start()
# wait for the interaction manager object shutdown as a signal to shutdown
self.interaction_manager.join()
if __name__ == "__main__":
Main()
【问题讨论】:
-
如您所说,这可能是为了防止您意外取消您可能不想取消的内容。
-
Main"class" 是我最近看到的对 OOP 的最严重滥用...... -
你永远不会费心去关闭线程。杀死主线程后,Python 仍然等待
InteractionManager线程停止。 double [Ctrl]+[C] 的 full 回溯立即揭示了这一点。如果您不希望它逗留,请使用daemon线程。 -
感谢主课评论,真的很有帮助
-
谢谢@MisterMiyagi,我明白了一般的想法,尽管第二个回溯如何揭示它,也不知道在第二个 ctrl-c 或什么之后,连接函数如何仍然存在否则使第二个回溯提到连接功能。
标签: python python-3.x