Asyncio的事件循环
事件循环
在事件循环中,咱们能够:
- 注销,执行和勾销调用
- 启动子过程,和内部过程进行通信
- 把耗时的函数调用委托给线程池解决
实质上。所有的事件循环都是期待事件产生,而后执行相应的调用。在此之前,咱们须要把行将产生的事件和对应执行的调用互相关联。
事件循环和线程的关系
从asyncio event loop policy文档,咱们得悉, event loop policy是一个过程全局对象,管制对该过程内所有event loop的治理。
过程的全局policy定义了该policy管控的context的含意,在每个context中治理离开独立的event loop. 默认的policy定义的context就是以后的线程, 也就是说不同的线程是不同的context,因而有不同的event loop。
通过定制event loop policy扭转get_event_loop(), set_event_loop(),new_event_loop()的默认行为。
每个context中只有一个running event loop
asyncio中 asyncio.run(),asyncio.get_event_loop(), asyncio.new_event_loop,asyncio.set_event_loop()的场景
asyncio.get_event_loop()
若:
- 以后线程为主线程,
- 以后线程没有启动event loop,
-以后线程没有调用async.set_event_loop(None)
调用asyncio.get_event_loop()办法会生成一个新的默认event loop,并设置为以后线程的事件循环。
此时,get_event_loop()相当于:
loop = asyncio.new_event_loop()asyncio.set_event_loop(loop)
若以后context有默认的event loop,并且没有被set_event_loop(None),则返回默认event loop,
aysncio.run()
调用该办法,会生成新的event loop并在办法调用完结时敞开该event loop。应该作为编写的普通用户异步程序的主入口存在。该办法原则上最好只调用一次。此时asyncio.run()相当于:
new_loop = asyncio.new_event_loop()asyncio.set_event_loop(new_loop)new_loop.run_until_complete(coro)asyncio.set_event_loop(None)new_loop.close()
示例总结:
>>> import asyncio>>> async def main(loop,desc: str):... cur_loop = asyncio.get_running_loop()... if cur_loop is loop:... print(desc, ': match')... else:... print(desc, ': not match')... print(f'Current running loop is :{id(cur_loop)}' )>>> loop = asyncio.get_event_loop()>>> loop2 = asyncio.get_event_loop()>>>loop is loop2True # get_event_loop()获得以后context默认的event loop,若没有则新生成一个。>>>>>> loop.run_until_complete(main(loop, 'loop.run_until_complete'))loop.run_until_complete : matchCurrent running loop is :140127062748856>>> loop.close() #close 以后的默认循环>>>>>> loop.run_until_complete(main(loop, 'loop.run_until_complete'))Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/base_events.py", line 560, in run_until_complete self._check_closed() File "/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/base_events.py", line 480, in _check_closed raise RuntimeError('Event loop is closed')RuntimeError: Event loop is closed# close()之后,这个event loop就彻底费了,然而,只有不调用set_event_loop(otherloop), 则loop仍然是以后context的默认event loop。>>>>>> loop3 = asyncio.new_event_loop()>>> loop3.run_until_complete(main(loop, 'loop.run_until_complete'))loop.run_until_complete : not matchCurrent running loop is :140127033794456# loop3是新生成的event loop ,然而并非以后context的默认event loop>>>>>> loop3.stop()>>> loop3.is_closed()False>>> loop3.run_until_complete(main(loop, 'loop.run_until_complete'))loop.run_until_complete : not matchCurrent running loop is :140127033794456# stop 一个event loop 只是暂停event loop , 还能再用。>>>>>> asyncio.set_event_loop(None)>>> loop5 = asyncio.get_event_loop()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/events.py", line 644, in get_event_loop % threading.current_thread().name)RuntimeError: There is no current event loop in thread 'MainThread'# 调用set_event_loop(None) 后,执行get_event_loop会产生例外,>>>>>> loop6 = asyncio.new_event_loop()>>> asyncio.set_event_loop(loop6)>>> loop7 = asyncio.get_event_loop()>>> loop6 is loop7True# 此时须要给以后context再set一个event loop才行>>>>>> loop4.run_until_complete(main(loop6, 'loop.run_until_complete'))loop.run_until_complete : not matchCurrent running loop is :140127033408816# 一个context中能够生成多个event loop,然而默认的event loop 只有一个。并且,只有event loop不被close(), 任何一个event loop都能run,然而正running的event loop只有一个>>>>>> asyncio.run(main(loop6, 'asyncio.run'))asyncio.run : not matchCurrent running loop is :140127033529008>>> loop8 = asyncio.get_event_loop()Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/events.py", line 644, in get_event_loop % threading.current_thread().name)RuntimeError: There is no current event loop in thread 'MainThread'.# 调用asyncio.run()相当于从新设定以后contex的默认loop , 应用完后,close以后的默认loop>>>
以上代码实例,起源自
https://gist.github.com/kaelz...
https://www.programcreek.com/...