We apologize that the translated content is not provided to this page.
前言
目前在写的自制消息推送服务器用到了多线程的方式进行处理,现在想改为使用高效率的协程进行处理。
过程
目前在搜索的过程中找到两种EventLoop的协程执行方法:
第一种
import asyncio
async def do_something():
pass
event_loop = asyncio.get_event_loop()
asyncio.set_event_loop(event_loop)
task = asyncio.ensure_future(do_something())
event_loop.run_until_complete(task) # 阻塞运行完自动停止loop
第二种
import asyncio
async def do_something():
pass
event_loop = asyncio.get_event_loop()
asyncio.set_event_loop(event_loop)
task = asyncio.ensure_future(do_something())
event_loop.run_forever() # 运行完不自动停止loop,一直阻塞
坑点
- 如果需要不断给loop添加协程,第二种执行方式无效,效率会因为阻塞运行与正常执行无差;
- 如果需要不断给永久运行中的loop添加协程,第一种和第二种执行方式均无效;
- 每次通过
asyncio.ensure_future
或event_loop.create_task
添加进loop后,都需要重新运行loop;
个人理解的图像
解决循环添加的问题
通过查找手册,发现使用方法asyncio.run_coroutine_threadsafe
可以动态添加协程。
import asyncio
from threading import Thread
event_loop = asyncio.get_event_loop()
async def do_something():
pass
def new_event_loop():
event_loop.run_forever() # 线程内阻塞
t = Thread(target=new_event_loop).start()
for i in range(100):
asyncio.run_coroutine_threadsafe(do_something(), loop=event_loop)
后记
网上给出一堆的协程示例代码也只是简单的固定任务运行,只字不提动态添加的情况也是挺有意思的现象,说不定文章都是抄袭的?