我试图timeout在到达方法后取消正在运行的线程concurrent.futures.wait,但程序仍运行 10 秒中指定的时间if url == "url_3":
import concurrent.futures
from time import sleep, time
sources = ["url_1", "url_2", "url_3"]
def get_request_header(url: str) -> str:
if url == "url_1":
sleep(0.8)
if url == "url_2":
sleep(0.9)
if url == "url_3":
sleep(10)
return f"{url}-headers"
start = time()
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(get_request_header, url) for url in sources]
completed, uncompleted = concurrent.futures.wait(futures, timeout=1.5)
for future in uncompleted:
future.cancel()
for future in completed:
print(future.result())
print(time() - start)
如果您在cancel()之后打印并检查状态,那么它仍然存在running并且实际上返回False
for future in uncompleted:
print(future)
print(future.cancel())
print(future)
需要通过timeout参数限制线程的工作,让未完成的线程停止工作,这有什么问题吗?
我也尝试过as_completed,但map不提供通过。
正如评论中所述,
@Amgarak正在运行的任务无法取消。但为了使主线程不会阻塞,您可以
ThreadPoolExecutor在没有上下文管理器的情况下创建它,并在最后使用shutdown参数显式调用该方法(它不会终止已运行任务的执行)(wait=False, cancel_futures=True)输出:
UPD 有一个糟糕的生活黑客
您可以将代码包装在函数中并创建守护线程
接下来,进入模块
concurrent.futures.thread,注释掉等待任务完成的行,然后执行正在运行的任务的线程将被取消。