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

Python多线程:任一线程返回True时立即触发逻辑并返回指定元组

解决方案

要实现你的需求,核心需要解决三个问题:线程间的终止信号传递、获取线程返回值、以及主线程的等待逻辑。以下是修改后的完整代码,附带详细说明:

关键改进点

  • 使用threading.Event作为线程终止信号,当任一线程成功返回时,触发事件让另一个线程立即退出循环
  • 用queue.Queue安全传递线程的返回结果,避免共享变量的锁问题
  • 主线程通过队列等待结果,同时设置超时时间(到指定截止时间的剩余时长)

修改后的完整代码

import threading
import datetime
import time
import random
from queue import Queue


def func1(stop_event, result_queue):
    current_time = datetime.datetime.now().time()
    deadline = datetime.time(17, 37)
    
    while current_time < deadline and not stop_event.is_set():
        rand_int = random.randint(1, 10)
        print(f"func1: {rand_int}")
        
        if rand_int == 1:
            print('func1 return True')
            result_queue.put((True, 'func1'))
            stop_event.set()  # 通知另一个线程停止
            return
        
        time.sleep(8)
        current_time = datetime.datetime.now().time()
    
    # 如果是超时退出且还没设置过事件,才放入失败结果(避免重复放入)
    if not stop_event.is_set():
        print('func1 return False')
        result_queue.put((False, ''))


def func2(stop_event, result_queue):
    current_time = datetime.datetime.now().time()
    deadline = datetime.time(17, 37)
    
    while current_time < deadline and not stop_event.is_set():
        rand_int = random.randint(1, 10)
        print(f"func2: {rand_int}")
        
        if rand_int == 10:
            print('func2 return True')
            result_queue.put((True, 'func2'))
            stop_event.set()  # 通知另一个线程停止
            return
        
        time.sleep(8)
        current_time = datetime.datetime.now().time()
    
    # 如果是超时退出且还没设置过事件,才放入失败结果
    if not stop_event.is_set():
        print('func2 return False')
        result_queue.put((False, ''))


def main():
    stop_event = threading.Event()
    result_queue = Queue()
    
    # 启动线程,传入终止信号和结果队列
    thread1 = threading.Thread(target=func1, args=(stop_event, result_queue))
    thread2 = threading.Thread(target=func2, args=(stop_event, result_queue))
    thread1.start()
    thread2.start()
    
    # 计算截止时间的时间戳,用于设置超时
    now = datetime.datetime.now()
    deadline = datetime.datetime(now.year, now.month, now.day, 17, 37)
    # 如果当前时间已经过了截止时间,直接返回失败
    if now >= deadline:
        stop_event.set()
        thread1.join()
        thread2.join()
        return (False, '')
    
    # 计算剩余超时时间(秒)
    timeout = (deadline - now).total_seconds()
    
    try:
        # 等待队列中的结果,超时则返回默认值
        result = result_queue.get(timeout=timeout)
    except:
        # 超时后触发终止信号,等待线程结束
        stop_event.set()
        thread1.join()
        thread2.join()
        result = (False, '')
    
    # 确保另一个线程也终止
    stop_event.set()
    thread1.join()
    thread2.join()
    
    return result


if __name__ == "__main__":
    result = main()
    print("最终结果:", result)

代码说明

  1. 终止信号stop_event:

    • 每个线程在循环中都会检查stop_event.is_set(),一旦事件被设置(任一线程成功返回时调用stop_event.set()),就会立即退出循环,停止执行
    • 主线程超时后也会设置这个事件,让两个线程都终止
  2. 结果传递result_queue:

    • 线程完成时把结果放入队列,主线程通过queue.get()获取第一个返回的结果,保证任一线程成功就立刻处理
    • 避免了使用共享变量需要加锁的复杂操作
  3. 超时处理:

    • 计算当前时间到截止时间的剩余秒数,作为queue.get()的超时时间
    • 超时后触发终止信号,等待两个线程结束,返回默认的(False, '')
  4. 线程清理:

    • 无论哪种情况,最后都会调用thread.join()等待线程完全结束,避免僵尸线程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:35:02