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

Python多进程能否运行异步函数?多进程任务无输出问题排查

正确实现多进程运行异步+同步任务的方案

问题根源拆解

  1. 异步函数不能直接传给multiprocessing.Process:Process依赖pickle序列化函数,但协程对象、未包装的异步函数无法被pickle,会触发PicklingError。
  2. 异步函数必须在事件循环中执行:直接调用异步函数只会得到协程对象,不会实际运行,从而出现"协程未等待"警告。
  3. 主进程提前退出会导致子进程被终止:如果主进程没等待子进程,启动后直接结束,function2的子进程也会跟着退出,导致无输出。
  4. Windows平台必须用if __name__ == '__main__'保护:否则会重复创建进程,引发异常或无输出。

完整可运行代码示例

import asyncio
from multiprocessing import Process
import time

# 你的异步WebSocket发送函数示例
async def SendSMS():
    while True:
        # 替换为实际的WebSocket发送逻辑
        print("Sending SMS via WebSocket...")
        await asyncio.sleep(2)

# 同步无限循环函数
def function2():
    while True:
        print("Function2 is running...")
        time.sleep(1)

# 异步函数的同步包装器:负责启动事件循环运行异步任务
def run_async_sms():
    # 在子进程中创建独立事件循环
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    # 运行异步任务(因SendSMS是无限循环,run_until_complete会持续阻塞)
    loop.run_until_complete(SendSMS())

if __name__ == '__main__':
    # 创建两个子进程
    p1 = Process(target=run_async_sms)
    p2 = Process(target=function2)

    # 启动进程
    p1.start()
    p2.start()

    # 主进程等待子进程结束(避免主进程提前退出终止子进程)
    p1.join()
    p2.join()

关键细节说明

  1. 异步函数包装:用run_async_sms同步函数包裹异步逻辑,让Process序列化普通同步函数,规避pickle错误。
  2. 事件循环隔离:子进程需重新创建事件循环,主进程的事件循环无法被子进程继承。
  3. 主进程阻塞等待:join()方法确保主进程不会提前退出,保证function2持续输出。
  4. Windows兼容性:if __name__ == '__main__'是Windows平台的强制要求,防止模块导入时重复创建进程。

针对你之前错误的对应解决

  • PicklingError:通过同步包装器避免直接传递异步函数/协程对象给Process。
  • 协程未等待警告:在包装器中用loop.run_until_complete()启动事件循环,真正执行协程逻辑。
  • TypeError:确保Process的target是可调用的函数(而非协程对象),需传参时用args参数传递,比如Process(target=run_async_sms, args=(param1, param2))。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 05:35:11