使用ThreadPoolExecutor忽略未使用的期货

时间:2019-01-02 17:02:05

标签: python future threadpoolexecutor

我正在使用fast()并行运行两个功能slow()ThreadPoolExecutor。如果fast()返回非None的结果,我想使用它,否则,请使用slow()的结果。这是一个示例:

from concurrent.futures import ThreadPoolExecutor
from time import sleep

def fast():
    sleep(2)
    return 'fast'

def slow():
    sleep(4)
    return 'slow'

def run_parallel():
    with ThreadPoolExecutor() as executor:
        fast_future = executor.submit(fast)
        slow_future = executor.submit(slow)

        fast_result = fast_future.result()
        if fast_result is not None:
            slow_future.cancel()
            return fast_result

        return slow_future.result()

print(run_parallel())

运行输出:

$ time python example.py 
fast

real    0m4.058s
user    0m0.041s
sys 0m0.011s

由于fast()返回了一个非None的值,所以我希望它用2s而不是4s,尤其是因为我在slow_future.cancel()的那一行。

我理想的语法如下:

combined_future = fast_future.orElse(slow_future)
return combined_future.result()

我该怎么做才能得到这种预期的行为?

1 个答案:

答案 0 :(得分:0)

这是由于无法取消较慢的将来(slow_future.cancel()返回False),因此线程池执行程序等待线程。 尝试类似的东西:

from concurrent.futures import ThreadPoolExecutor, as_completed
from time import sleep

abort_flag = False


def fast():
    for i in range(20):
        if abort_flag:
            return None
        sleep(.1)
    return 'fast'


def slow():
    for i in range(40):
        if abort_flag:
            return None
        sleep(.1)
    return 'slow'


def run_parallel():
    global abort_flag
    with ThreadPoolExecutor() as executor:
        abort_flag = False
        fast_future = executor.submit(fast)
        slow_future = executor.submit(slow)
        for f in as_completed((fast_future, slow_future)):
            result = f.result()
            if result is not None:
                abort_flag = True
                return result


print(run_parallel())