Asyncio的事件循环eventloop在事件循环中,我们可以:- 注册、执行和取消调用- 启动子进程,与外部进程通信- consumer函数调用时本质上委托给线程池来处理。所有的事件循环都在等待事件发生,然后执行相应的调用。在此之前,我们需要将即将发生的事件与相应的执行调用相关联。事件循环与线程的关系从asyncio事件循环策略文档中我们知道,事件循环策略是一个进程全局对象,控制着进程中所有事件循环的管理。进程的全局策略定义了该策略控制的上下文的含义,并在每个上下文中管理单独且独立的事件循环。默认策略定义的上下文是当前线程,也就是说不同的线程有不同的上下文,所以有不同的事件循环。通过自定义事件循环策略更改get_event_loop()、set_event_loop()、new_event_loop()的默认行为。每个context中只有一个正在运行的事件循环asyncio.run()、asyncio.get_event_loop()、asyncio.new_event_loop、asyncio.set_event_loop()inasyncio如果asyncio.get_event_loop():当前线程为主线程,当前threadisnotstartedeventloop,-当前线程没有调用async.set_event_loop(None)调用asyncio.get_event_loop()方法会生成一个新的默认事件循环,并将其设置为当前线程的事件循环。此时get_event_loop()等同于:loop=asyncio.new_event_loop()asyncio.set_event_loop(loop)如果当前上下文有默认事件循环且不是set_event_loop(None),则返回默认事件循环,aysncio.run()调用此方法将生成一个新的事件循环,并在方法调用结束时关闭事件循环。它应该作为编写普通用户异步程序的主要入口点存在。理想情况下,此方法应该只调用一次。此时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()示例总结:>>>importasyncio>>>asyncdefmain(loop,desc:str):...cur_loop=asyncio.get_running_loop()...ifcur_loopisloop:...print(desc,':match')...else:...print(desc,':notmatch')...print(f'Currentrunningloopis:{id(cur_loop)}')>>>loop=asyncio.get_event_loop()>>>loop2=asyncio.get_event_loop()>>>loopisloop2True#get_event_loop()获取当前上下文的默认事件循环,如果没有,生成一个新的。>>>>>loop.run_until_complete(main(loop,'loop.run_until_complete'))loop.run_until_complete:matchCurrentrunningloopis:140127062748856>>>loop.close()#关闭当前默认循环>>>>>loop.run_until_complete(main(loop,'loop.run_until_complete'))Traceback(最近调用最后一次):文件“”,第1行,在文件“/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/base_events.py”,第560行,在run_until_completeself._check_closed()文件“/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/base_events.py”,行480,in_check_closedraiseRuntimeError('Eventloopisclosed')RuntimeError:Eventloopisclosed#close()之后,这个事件循环就完全用完了,但是,只要不调用set_event_loop(otherloop),循环还在current上下文的默认事件循环。>>>>>>loop3=asyncio.new_event_loop()>>>loop3.run_until_complete(main(loop,'loop.run_until_complete'))loop.run_until_complete:notmatchCurrentrunningloopis:140127033794456#loop3是新生成的事件循环,但不是当前上下文的默认事件循环>>>>>>loop3.stop()>>>loop3.is_closed()False>>>loop3.run_until_complete(main(loop,'loop.run_until_complete'))loop.run_until_complete:notmatchCurrentrunningloopis:140127033794456#stop一个eventloop只是挂起eventloop,可以再次使用。>>>>>asyncio.set_event_loop(None)>>>loop5=asyncio.get_event_loop()Traceback(最近调用最后):文件“”,第1行,在文件“/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/events.py”,第644行,在get_event_loop%threading.current_thread().name)RuntimeError:Thereisnocurrenteventloopinthread'MainThread'#callset_event_loop(None),get_event_loop的执行会产生异常,>>>>>>loop6=asyncio.new_event_loop()>>>asyncio.set_event_loop(loop6)>>>loop7=asyncio.get_event_loop()>>>loop6isloop7True#这时候需要给当前上下文设置一个事件循环>>>>>>loop4.run_until_complete(main(loop6,'loop.run_until_complete'))loop.run_until_complete:notmatchCurrentrunningloopis:140127033408816#can在一个上下文中使用会生成多个事件循环,但默认事件循环只有一个。并且,只要事件循环不是closed(),任何事件循环都可以运行,但是运行的事件循环只有一个>>>>>>asyncio.run(main(loop6,'asyncio.run'))asyncio.run:notmatchCurrentrunningloopis:140127033529008>>>loop8=asyncio.get_event_loop()Traceback(最近一次调用last):文件“”,第1行,在文件“/home/shone/miniconda2/envs/python37/lib/python3.7/asyncio/events.py”,第644行,在get_event_loop%threading.current_thread().name)RuntimeError:Thereisnocurrenteventloopinthread'MainThread'.#callasyncio.run()相当于重置当前上下文的默认循环。使用完 后,关闭当前默认循环>>>以上代码示例来自 https://gist.github.com/kaelz...https://www.programcreek.com/...