You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python并发:等待多Future中一个返回True后取消其余任务

解决方案:用ThreadPoolExecutor实现“先完成且符合条件则终止其他任务”

刚好遇到过类似的场景,用concurrent.futures的as_completed()配合线程终止信号就能完美解决你的需求,直接上代码和解释:

核心思路

  1. 用as_completed()实时监听任务完成状态,哪个任务先结束就先处理它的返回值
  2. 一旦拿到返回True的结果,立刻给其他任务发送终止信号(因为线程无法强行终止,让任务主动退出更安全)
  3. 尝试取消还未开始执行的任务(避免资源浪费)

完整代码示例

import concurrent.futures
import time
import random
from threading import Event

def long_running_task(stop_event):
    """模拟你的耗时任务:获取代理、发送HTTP请求等"""
    print("任务启动中...")
    # 模拟分步执行的耗时操作,方便中途检查终止信号
    for step in range(5):
        # 每次执行步骤前检查是否需要终止
        if stop_event.is_set():
            print("任务收到终止指令,提前退出")
            return False
        # 模拟随机耗时(替换成你实际的业务逻辑)
        time.sleep(random.uniform(0.3, 1.5))
        print(f"任务完成第 {step+1} 步")
    
    # 模拟业务返回结果(替换成你实际的返回判断逻辑)
    final_result = random.choice([True, False])
    print(f"任务执行完毕,返回值: {final_result}")
    return final_result

def main():
    # 创建一个事件对象,用于跨线程传递终止信号
    stop_signal = Event()

    with concurrent.futures.ThreadPoolExecutor(max_workers=2) as executor:
        # 提交两个任务,把终止信号传入
        task_futures = [
            executor.submit(long_running_task, stop_signal),
            executor.submit(long_running_task, stop_signal)
        ]

        # 遍历已完成的任务
        for completed_future in concurrent.futures.as_completed(task_futures):
            try:
                result = completed_future.result()
                if result is True:
                    print("✅ 找到符合条件的任务结果,开始终止其他任务")
                    # 触发终止信号,通知正在运行的任务主动退出
                    stop_signal.set()
                    # 取消所有未完成的任务(仅对未启动的任务有效)
                    for future in task_futures:
                        if future != completed_future and not future.done():
                            future.cancel()
                    # 跳出循环,进入后续流程
                    break
            except Exception as e:
                print(f"❌ 任务执行出错: {str(e)}")
                # 可根据需求决定是否终止其他任务,这里继续等待其他任务

    # 后续业务流程
    print("\n===== 进入后续代码逻辑 =====")
    # 这里写你的后续处理代码

if __name__ == "__main__":
    main()

关键细节解释

  • as_completed()方法:它会按任务完成的先后顺序返回Future对象,而不是按提交顺序,完美契合你“哪个先完成就先检查”的需求。
  • threading.Event():这是线程安全的信号传递方式,因为Python的线程无法被强行终止(强行终止可能导致资源泄漏),所以让任务主动检查stop_signal的状态,是最安全的终止方式。
  • Future.cancel():这个方法只能取消还处于pending状态(未被调度执行)的任务,如果任务已经在运行,cancel()会返回False,这时候就靠stop_signal让任务主动退出。
  • 异常处理:任务执行中可能出现请求失败、代理异常等错误,用try-except包裹future.result()可以避免程序崩溃,同时你可以根据需求决定是否终止其他任务。

内容的提问来源于stack exchange,提问作者slashms

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:00:59