我正在使用新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()
and Future.cancel()
)仅在 Futures 尚未启动或完成时才起作用,在这种情况下这是没有意义的。我想立即打断未来。
我的用例很简单:当用户按下 Control-C 时,脚本应该像任何表现良好的脚本一样立即退出。这就是我想要的。
那么在使用时获得这种行为的正确方法是什么concurrent.futures
?