Python中如何将异步永久线程与其他线程一同运行?
问题分析与修复方案
我来帮你拆解下为什么第二个线程没启动,以及怎么解决这个问题:
核心问题
1. 线程创建时的立即调用阻塞了主线程
你在创建t1线程时写了:
t1 = threading.Thread(target=asyncio.run, args=(class1.funcClass1(), ))
这里的class1.funcClass1()是直接调用了函数,而不是把函数对象传给线程。因为funcClass1里有loop.run_forever(),这会导致主线程在创建t1之前就直接进入了死循环,后面创建t2、启动t2的代码根本没机会执行——这就是你看不到Class2输出的根本原因。
2. 共享事件循环的线程安全问题
默认情况下,asyncio的事件循环是和线程绑定的。你在主线程调用asyncio.get_event_loop()拿到的循环属于主线程,子线程直接复用这个循环会导致行为异常,甚至在新版本Python中直接报错。
修复后的代码
修改Classes.py
import asyncio class Class1: async def _funcClass1(self): while True: await asyncio.sleep(5) print('Hello async/threading world') def funcClass1(self): # 为当前线程创建独立的事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # 将异步任务加入循环 loop.create_task(self._funcClass1()) # 启动循环 loop.run_forever() class Class2: async def _funcClass2(self, name): print(f'Hello {name}') def funcClass2(self, name): # 为当前线程创建独立的事件循环 loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # 运行异步任务直到完成 loop.run_until_complete(self._funcClass2(name))
修改main.py
from Classes import Class1, Class2 import threading class1 = Class1() class2 = Class2() if __name__ == "__main__": # 直接将函数对象传给线程target,避免提前调用阻塞主线程 t1 = threading.Thread(target=class1.funcClass1) # 正确传递参数给Class2的方法 t2 = threading.Thread(target=class2.funcClass2, args=('john', )) t1.start() t2.start() t1.join() t2.join()
关键修改点说明
- 避免线程创建时的提前调用:把
class1.funcClass1()改成class1.funcClass1,让线程在启动后再执行函数,不会阻塞主线程创建其他线程。 - 每个线程独立管理事件循环:在每个类的方法中创建专属的事件循环,避免共享主线程循环带来的线程安全问题。
- 修正Class2的参数传递:给
funcClass2添加name参数,确保能正确接收并传递给异步函数。
现在运行代码,你会先看到Hello john,之后每隔5秒就会输出Hello async/threading world,两个线程都能正常工作了。
内容的提问来源于stack exchange,提问作者AlgoQ
相关产品推荐
相关产品推荐

