【发布时间】:2015-05-24 12:13:27
【问题描述】:
我正在使用新的concurrent.futures 模块(它也有一个 Python 2 反向端口)来执行一些简单的多线程 I/O。我无法理解如何彻底终止使用此模块开始的任务。
查看以下 Python 2/3 脚本,它重现了我看到的行为:
#!/usr/bin/env python
from __future__ import print_function
import concurrent.futures
import time
def control_c_this():
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
future1 = executor.submit(wait_a_bit, name="Jack")
future2 = executor.submit(wait_a_bit, name="Jill")
for future in concurrent.futures.as_completed([future1, future2]):
future.result()
print("All done!")
def wait_a_bit(name):
print("{n} is waiting...".format(n=name))
time.sleep(100)
if __name__ == "__main__":
control_c_this()
当此脚本运行时,使用常规的 Control-C 键盘中断似乎无法彻底终止。我在 OS X 上运行。
- 在 Python 2.7 上,我必须从命令行使用
kill来终止脚本。 Control-C 会被忽略。 - 在 Python 3.4 上,如果按两次 Control-C,则可以正常工作,但随后会转储许多奇怪的堆栈跟踪。
我在网上找到的大多数文档都在讨论如何使用旧的 threading 模块彻底杀死线程。似乎都不适用于这里。
并且concurrent.futures 模块中提供的所有停止内容的方法(如Executor.shutdown() 和Future.cancel())仅在Futures 尚未开始或完成时才有效,在这种情况下这是没有意义的。我想立即打断Future。
我的用例很简单:当用户按下 Control-C 时,脚本应该像任何表现良好的脚本一样立即退出。这就是我想要的。
那么在使用concurrent.futures 时获得这种行为的正确方法是什么?
【问题讨论】:
-
阅读related question about Java,我发现杀死线程不是你通常会做的事情,因为它会使你的程序状态不一致。就我而言,我不认为这是一个问题,因为我只想退出整个程序。还提到了setting some shared variable,线程可以读取以了解何时自行终止。不确定这种方法是否适用于 Python。
-
请注意,Ctrl+Break 会起作用,即使 Ctrl+C 不起作用。
-
@jedwards - 使用 Python 2 我正在尝试 Command + 。 (这显然是 OS X 上的 Control + Break),它似乎不起作用。实际上,似乎等同于 Control + C。
标签: python multithreading concurrent.futures