如何同时无限运行异步Twisted reactor与asyncio事件循环
问题解决方法
你可以通过两种方案解决两个事件循环阻塞主线程的问题,优先选择合并事件循环的方案,避免多线程额外开销和安全问题。
方案1:合并Twisted与asyncio事件循环(推荐)
Twisted官方提供了asyncio反应器支持,可以直接将Twisted的事件逻辑挂载到asyncio的循环上,只运行一个循环即可同时驱动两个库的逻辑,实现代码如下:
import asyncio # 第一步:必须在导入twisted的reactor前先安装asyncio反应器 from twisted.internet import asyncioreactor asyncioreactor.install(asyncio.get_event_loop()) # 第二步:导入reactor,执行Twisted侧的初始化逻辑 from twisted.internet import reactor # your_twisted_lib_init() 此处替换为你的Twisted库初始化、监听注册逻辑 # 第三步:执行asyncio侧的初始化逻辑 loop = asyncio.get_event_loop() # loop.create_task(your_asyncio_lib_task()) 此处替换为你的asyncio库任务注册逻辑 # 最后仅需启动Twisted的reactor,会自动同步驱动asyncio循环 reactor.run()
方案2:子线程单独运行其中一个事件循环
如果因为版本兼容等问题无法合并循环,可以将其中一个事件逻辑放到守护子线程中运行,主线程运行另一个循环:
import threading import asyncio from twisted.internet import reactor # 定义asyncio循环运行逻辑,放到子线程执行 def run_asyncio_service(): loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) # 注册asyncio库的任务 # loop.create_task(your_asyncio_lib_task()) loop.run_forever() # 启动asyncio子线程 asyncio_thread = threading.Thread(target=run_asyncio_service, daemon=True) asyncio_thread.start() # 主线程运行Twisted逻辑 # your_twisted_lib_init() 此处替换为Twisted库初始化逻辑 reactor.run()
多线程方案注意事项
- 如果需要在asyncio任务中调用Twisted的接口,必须通过
reactor.callFromThread(目标函数, 参数)提交调用请求,不能直接调用 - 如果需要在Twisted回调中调用asyncio的接口,必须通过
asyncio.run_coroutine_threadsafe(目标协程, asyncio_loop实例)提交调用请求,否则会出现线程安全异常
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

