Python Asyncio监听循环在闲置主循环中无法运行问题求助
问题分析与修复方案
核心问题
你的代码中listener()协程无法运行的根本原因是事件循环实例不匹配:
- 在
start_IO函数中,你手动创建了self.loop并设置为当前线程的事件循环,但随后调用asyncio.run(main())会自动创建一个全新的事件循环来执行main协程,完全忽略了你之前创建的self.loop。 - 后续调用
asyncio.run_coroutine_threadsafe(listener(), self.loop)时,传入的self.loop实际上是一个未启动的空循环,因此listener协程永远不会被调度执行。
修复步骤
修改start_IO函数,移除asyncio.run(),直接使用你手动创建的self.loop来运行协程:
def start_IO(): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) # 替换asyncio.run,直接用创建的loop运行协程 self.loop.run_until_complete(main()) print("Main Exited")
额外优化(可选)
你当前用time.sleep(0.1)等待循环初始化的方式不可靠,改用线程同步事件能确保循环完全启动后再执行后续逻辑:
def start_IOLoop_thread(self): loop_ready = threading.Event() # 新增同步事件 async def inf_loop(): while True: await asyncio.sleep(1) async def main(): loop_ready.set() # 循环启动后触发事件 await inf_loop() def start_IO(): self.loop = asyncio.new_event_loop() asyncio.set_event_loop(self.loop) self.loop.run_until_complete(main()) print("Main Exited") threading.Thread(target=start_IO, daemon=True).start() loop_ready.wait() # 等待循环启动,替代time.sleep
测试验证
修改后,可在主函数中添加队列数据测试:
if __name__ == "__main__": C = Client() C.streamQ.put_nowait("测试数据") # 往队列添加数据 input("Enter to exit")
此时会输出预期内容:
Starting Listener Listener Running 测试数据
内容的提问来源于stack exchange,提问作者Mandias
相关产品推荐
相关产品推荐

