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

如何在Python中并行执行两个含底层请求的函数(无需异步重构)

如何在Python中并行执行两个含底层请求的函数(无需异步重构)

你的思路是对的——用threading模块来并行执行两个IO密集型的请求函数,完全不需要重构为异步代码,因为IO密集型任务在Python线程中能有效利用等待时间(GIL会在网络IO等待时释放,让其他线程运行)。不过你的代码存在一些冗余和可以简化的地方,下面我来逐一分析并给出优化方案:


一、你的原代码核心逻辑是可行的,但存在冗余

你通过threading.Thread启动两个线程执行请求函数,用队列传递结果,最后join等待线程完成——这部分确实能实现并行执行。但后续的while循环轮询队列是完全多余的:

  • thread.join()会阻塞主线程,直到对应的子线程完全终止
  • 子线程的worker函数在执行完请求后,已经把结果put进队列了,线程终止意味着put操作已经完成,队列里一定有结果
  • 因此你不需要轮询队列是否为空,直接调用queue.get()就能立即拿到结果

另外,原代码的while循环还存在bug:

  • 把第二个队列的结果错误赋值给first变量(应该是second = queue_second.get(...))
  • 错误地通过queue.empty()判断任务是否完成,这在join之后完全没必要(线程已经结束,队列不可能为空)

二、简化后的代码

下面是优化后的版本,保留你的核心并行逻辑,去掉冗余代码并修复潜在问题:

1. 基础简化版

import threading
import queue

def worker(function, queue_prepared, *args):
    # 执行请求函数并将结果放入队列
    result = function(*args)
    queue_prepared.put(result)

def launch_threads(param1, param2):
    queue_first = queue.Queue()
    queue_second = queue.Queue()
    
    # 启动两个线程,分别执行不同的请求函数
    thread_first = threading.Thread(
        target=worker, 
        args=(request1, queue_first, param1, param2)
    )
    thread_second = threading.Thread(
        target=worker, 
        args=(request2, queue_second, param1)
    )
    
    thread_first.start()
    thread_second.start()
    
    # 等待两个线程都执行完毕
    thread_first.join()
    thread_second.join()
    
    # 线程结束后,队列中肯定有结果,直接取出返回
    return queue_first.get(), queue_second.get()

# 调用并获取结果
result1, result2 = launch_threads(param1, param2)

2. 增加异常处理的健壮版本

如果请求函数可能抛出异常(比如网络错误),可以在worker中捕获异常并传递给主线程,避免子线程悄悄出错:

import threading
import queue

def worker(function, queue_prepared, *args):
    try:
        result = function(*args)
        # 用元组标记成功状态和结果
        queue_prepared.put((True, result))
    except Exception as e:
        # 传递异常信息给主线程
        queue_prepared.put((False, e))

def launch_threads(param1, param2):
    queue_first = queue.Queue()
    queue_second = queue.Queue()
    
    thread_first = threading.Thread(
        target=worker, 
        args=(request1, queue_first, param1, param2)
    )
    thread_second = threading.Thread(
        target=worker, 
        args=(request2, queue_second, param1)
    )
    
    thread_first.start()
    thread_second.start()
    thread_first.join()
    thread_second.join()
    
    # 处理结果和异常
    success1, res1 = queue_first.get()
    success2, res2 = queue_second.get()
    
    if not success1:
        raise res1  # 抛出子线程的异常
    if not success2:
        raise res2
    
    return res1, res2

# 调用时可以捕获异常
try:
    result1, result2 = launch_threads(param1, param2)
except Exception as e:
    print(f"请求出错: {e}")

三、关于Python线程与IO密集型任务的说明

因为你的任务是发送HTTP请求(IO密集型),Python的threading模块完全能实现有效并行:

  • Python的GIL(全局解释器锁)在遇到IO等待(比如等待网络响应)时会自动释放,让其他线程获得执行权
  • 这意味着两个请求会同时发起,不需要等待第一个请求完成再执行第二个,能有效节省总耗时

备注:内容来源于stack exchange,提问作者Carabes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:38:09