如何停止 ThreadPoolExecutor.map 并按 CTRL-C 退出?

par*_*vus 5 python-multithreading python-3.x

Python 脚本多次执行 IO 密集型函数(数量级:5000 到 75000 之间的任意次数)。通过使用这仍然相当有效

def _iterator(): ...  # yields 5000-75000 different names
def _thread_function(name): ...

with concurrent.futures.ThreadPoolExecutor(max_workers=11) as executor:
    executor.map(_thread_function, _iterator(), timeout=44)
Run Code Online (Sandbox Code Playgroud)

如果用户按下 CTRL-C,它只会弄乱单个线程。我希望它停止启动新线程;并完成当前正在进行的线程或立即终止它们,等等。

我怎样才能做到这一点?

Boy*_*tov 2

concurrent.futures.Executor.map 中的异常处理可能会回答您的问题。

本质上,来自concurrent.futures.Executor.map的文档

如果 func 调用引发异常,则当从迭代器检索其值时,将引发该异常。

由于您永远不会从 map() 检索值,因此主线程中永远不会引发异常。

此外,根据PEP 255

如果生成器函数引发或传递未处理的异常(包括但不限于 StopIteration),则该异常将以通常的方式传递给调用者,并随后尝试恢复生成器函数引发 StopIteration。换句话说,未处理的异常会终止生成器的使用寿命。

因此,如果您将代码更改为(注意循环for):

def _iterator(): ...  # yields 5000-75000 different names
def _thread_function(name): ...

with concurrent.futures.ThreadPoolExecutor(max_workers=11) as executor:
    for _ in executor.map(_thread_function, _iterator(), timeout=44):
        pass
Run Code Online (Sandbox Code Playgroud)

InterruptedError在主线程中引发,并通过生成器 ( executor.map(_thread_function, _iterator(), timeout=44)) 来终止它。