首页 > 解决方案 > Python并发第一个结果结束等待尚未完成的结果

问题描述

我想做的是继续……在第一个 True 之后,不关心尚未完成的 I/O 绑定任务。在下面的情况下 two() 是第一个也是唯一的 True 所以程序需要像这样执行:

Second
Move on..

不是:

Second
First
Third
Move on...

import concurrent.futures
import time


def one():
    time.sleep(2)
    print('First')
    return False


def two():
    time.sleep(1)
    print('Second')
    return True


def three():
    time.sleep(4)
    print('Third')
    return False


tasks = [one, two, three]
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
    for t in range(len(tasks)):
        executor.submit(tasks[t])

print('Move on...')

标签: pythonmultithreadingconcurrencymultiprocessing

解决方案


问题concurrent.futures.ThreadPoolExecutor在于,一旦提交任务,它们将运行到完成,因此程序将打印“继续...”但如果实际上没有其他事情可做,程序将不会终止,直到函数onethree终止并且(和打印他们的消息)。所以程序保证运行至少 4 秒。

最好使用模块中支持杀死所有未完成任务的方法的ThreadPool类。最接近方法的可能是使用该方法,但这需要一个工作函数用于所有 3 个任务。但是我们可以使用指定一个回调函数来在结果可用时调用:multiprocessing.poolterminateas_completedimap_unorderedapply_async

from multiprocessing.pool import ThreadPool
import time
from threading import Event

def one():
    time.sleep(2)
    print('First')
    return False


def two():
    time.sleep(1)
    print('Second')
    return True


def three():
    time.sleep(4)
    print('Third')
    return False

def my_callback(result):
    if result:
        executor.terminate() # kill all other tasks
        done_event.set()

tasks = [one, two, three]
executor = ThreadPool(3)
done_event = Event()
for t in tasks:
    executor.apply_async(t, callback=my_callback)
done_event.wait()
print("Moving on ...")

推荐阅读