我试图遍历一大串字符串(大约80,000),生成一个HTTP请求并处理响应,直到获得正确的字符串为止。我将列表和执行请求的函数传递给ThreadPoolExecutor.map()
函数,然后遍历结果。
一旦从HTTP服务器收到正确的响应,我想取消所有剩余的期货并关闭脚本。为了简化编程,我希望不必自己跟踪每个未来。
我尝试使用shutdown()
,但是无论是否指定等待,脚本都不会在所有排队的期货都完成之前结束。因此,如果列表中的字符串2000是正确的值,我仍然必须等待下一个78,000个期货完成,这可能会花费大量时间。
是否可以告诉ThreadPoolExecutor其余任务是不必要的,甚至不需要启动它们?
答案 0 :(得分:1)
如果您可以切换到Python 3.9,则可以使用此功能built-in to the shutdown method:
如果cancel_futures为True,则此方法将取消执行者尚未开始运行的所有未决期货。不论cancel_futures的值如何,所有已完成或正在运行的期货都不会被取消。
答案 1 :(得分:1)
您可以cancel()
个期货。我看到您在问题中表示您不希望追踪期货,但这可能是您的最佳选择,而且看起来并不难:
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
def process(duration):
print(f"processing with duration {duration}")
time.sleep(duration)
if duration == 3:
return "result found"
with ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(process, i) for i in range(80000)]
for future in as_completed(futures):
if future.result() == "result found":
executor.shutdown(wait=False)
print("shutdown")
for f in futures:
if not f.done():
f.cancel()
break
print("about to exit")
答案 2 :(得分:0)
您可以使用Event
对象来控制 transform 函数的执行。
import concurrent.futures
import threading
evt = threading.Event()
def transform(arg):
if evt.is_set():
return None
...
return ret
with concurrent.futures.ThreadPoolExecutor() as pool:
for result in pool.map(transform, data):
if result == ...:
evt.set()
break