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

如何在Python线程中后台运行两个协程?

问题分析与修复方案

核心问题

你的代码无法正常打印消息,主要有两个关键问题:

  • 同步阻塞调用卡住事件循环:heartbeat里用了time.sleep(30),这是同步阻塞函数,会彻底卡住asyncio事件循环,导致listen协程完全没有机会执行消息监听操作。
  • client初始化顺序错误:当前代码先启动线程再初始化client,线程内的协程会访问到未初始化的client,引发错误或异常。

修复后的代码

import threading
import asyncio

async def heartbeat(client):
    while True:
        await client.websok.send_message('\n')
        # 替换同步sleep为异步的asyncio.sleep,不阻塞事件循环
        await asyncio.sleep(30)

async def listen(client):
    while True:
        msg = await client.websok.receive_message()
        print(msg)

def background_loop(client):
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    tasks = [heartbeat(client), listen(client)]
    loop.run_until_complete(asyncio.gather(*tasks))

# Main code
# 先初始化client,确保线程启动前client已经就绪
client = # 这里完成你的API连接创建逻辑

# 将client作为参数传入线程函数,避免全局变量的潜在问题
t = threading.Thread(target=background_loop, args=(client,))
t.start()

关键修改说明

  • 替换time.sleep为asyncio.sleep:asyncio.sleep是异步非阻塞的,只会让当前协程暂停,事件循环可以在这段时间去执行listen协程的消息监听操作。
  • 调整client初始化顺序:先完成client的创建,再启动线程,确保线程内的协程能访问到已就绪的连接对象。
  • 将client作为参数传入线程函数:避免使用全局变量,减少多线程环境下的变量访问风险,让代码逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:12:08