python事件循环_简单了解一下事件循环(Event Loop)
關于我
一個有思想的程序猿,終身學習實踐者,目前在一個創業團隊任team lead,技術棧涉及Android、Python、Java和Go,這個也是我們團隊的主要技術棧。
Github:https://github.com/hylinux1024
微信公眾號:終身開發者(angrycode)
0x00 事件循環(Event Loop)
在前文《為何你還不懂得如何使用Python協程
》 中提到協程是通過asyncio包中的高級API來啟動的。而asyncio模塊中的核心就是事件循環(Event Loop)。它可用于執行異步任務、事件回調、執行網絡IO操作和運行子進程。官方的文檔也是建議開發者應該盡量使用asyncio包提供的高級的API,避免直接使用Event Loop對象中的方法。
系統提供的底層能力的功能模塊例如網絡連接、文件IO等都會使用到loop。
大多數情況下,這些高級API可以滿足眾多使用場景,但作為一個有追求的猿類,應該要有一點點探索的精神,看看在asyncio封裝之下的Event Loop。
獲取Event Loop對象
asyncio.get_running_loop()
獲取當前系統線程正在使用的loop對象
asyncio.get_event_loop()
獲取當前正在使用的loop對象。如果當前系統線程還沒有loop對象,那么就會創建一個新的loop對象,并使用asyncio.set_event_loop(loop)方法設置到當前系統線程中。
asyncio.new_event_loop()
創建一個新的loop對象
asyncio.set_event_loop(loop)
將loop設置成系統線程使用的對象
Event Loop對象的常用方法
如果使用類似asyncio.run()這些高級API,以下這些方法,基本上很少會用到,建議通讀一下,大概知道loop對象擁有哪些API,了解以下底層的實現細節。
啟動和停止
loop.run_until_complete(future)
future對象執行完成才返回
loop.run_forever()
一直運行,直到調用了loop.stop()方法
loop.stop()
停止loop對象
loop.is_running()
判斷loop是否正在運行
loop.is_closed()
判斷loop是否關閉
loop.close()
關閉loop對象
coroutine loop.shutdown_asyncgens()
try:
loop.run_forever()
finally:
loop.run_until_complete(loop.shutdown_asyncgens())
loop.close()
回調方法
loop.call_soon(callback, *args, context=None)
在事件循環的下一次迭代中執行callback方法,args是方法中的參數
loop.call_soon_threadsafe(callback, *args, context=None)
線程安全的call_soon()
iimport asyncio
import time
def hello_world(loop):
print('Hello World')
time.sleep(3) # 模擬長時間操作
loop.stop()
loop = asyncio.get_event_loop()
# 使用loop執行 hello_world()
loop.call_soon(hello_world, loop)
# 會一直阻塞,直到調用了stop方法
try:
loop.run_forever()
finally:
loop.close()
可延遲的回調方法
可設置延遲執行的方法
loop.call_later(delay, callback, *args, context=None)
延遲delay秒后執行
loop.call_at(when, callback, *args, context=None)
在指定時間點執行
loop.time()
返回當前時間
import asyncio
import datetime
def display_date(end_time, loop):
print(datetime.datetime.now())
if (loop.time() + 1.0) < end_time:
# 1秒后執行
loop.call_later(1, display_date, end_time, loop)
else:
loop.stop()
loop = asyncio.get_event_loop()
# 執行5秒
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)
# 一直運行,等待stop的調用
try:
loop.run_forever()
finally:
loop.close()
執行結果打印5秒時間點
2019-05-09 22:34:47.885412
2019-05-09 22:34:48.887513
2019-05-09 22:34:49.889396
2019-05-09 22:34:50.894316
2019-05-09 22:34:51.898457
創建Future和Tasks
loop.create_future()
創建一個綁定事件循環的future對象
loop.create_task(coro)
將coro放入調度,并返回task對象
loop.set_task_factory(factory)
設置任務工廠
loop.get_task_factory()
返回任務工廠,有可能返回None
創建網絡連
coroutine loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None)
指定host、port等參數創建網絡連接
coroutine loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)
創建UDP連接
coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None)
創建Unix連接
coroutine loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, start_serving=True)
創建TCP服務
coroutine loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, start_serving=True)
創建Unix服務
coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None)
封裝已建立的連接,返回元組(transport, protocol)
Event Loop 的實現
asyncio 的事件循環有兩種不同的實現:SelectorEventLoop和 ProactorEventLoop,它們的父類是AbstractEventLoop
SelectorEventLoop
這個是asyncio默認使用的Event Loop實現,支持unix和windows平臺
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
ProactorEventLoop
這個是Windows平臺專有的實現
import asyncio
import sys
if sys.platform == 'win32':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
0x01 總結
事件循環是asyncio的核心,asncio模塊的很多高級接口是通過封裝Event Loop對象來實現的。它提供了執行異步任務、事件回調、執行網絡IO操作和運行子進程的能力。
本文是通過官方文檔對事件循環的概念和它的常見API做了一個大概的了解。作為《前文》的補充
0x02 引用
https://docs.python.org/3/library/asyncio-eventloop.html
總結
以上是生活随笔為你收集整理的python事件循环_简单了解一下事件循环(Event Loop)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在长途运输时小鹏G9在什么位置断全车`电
- 下一篇: 手机投屏到电视的5种方法_安卓手机、苹果