Python的Asyncio模塊提供了管理事件、協程、任務和線程的方法,以及編寫并發代碼的原語。此模塊的主要組件和概念包括:
- 事件循環 : 在Asyncio模塊中,每一個進程都有一個事件循環。
- 協程 : 這是子程序的泛化概念。協程可以在執行期間暫停,這樣就可以等待外部的處理(例如IO)完成之后,從之前暫停的地方恢復執行。
- Futures : 定義了
Future
對象,和concurrent.futures
模塊一樣,表示尚未完成的計算。 - Tasks : 這是Asyncio的子類,用于封裝和管理并行模式下的協程。
本節中重點討論事件,事實上,異步編程的上下文中,事件無比重要。因為事件的本質就是異步。
1. 什么是事件循環
在計算系統中,可以產生事件的實體叫做事件源,能處理事件的實體叫做事件處理者。
此外,還有一些第三方實體叫做事件循環。它的作用是管理所有的事件,在整個程序運行過程中不斷循環執行,追蹤事件發生的順序將它們放到隊列中,當主線程空閑的時候,調用相應的事件處理者處理事件。
最后,我們可以通過下面的偽代碼來理解事件循環:
while(1) {
events = getEvents();
for (e in events)
processEvent(e);
}
所有的事件都在 ** while
**循環中捕捉,然后經過事件處理者處理。事件處理的部分是系統唯一活躍的部分,當一個事件處理完成,流程繼續處理下一個事件。
2. 準備工作
Asyncio提供了以下方法來管理事件循環:
- **
loop = get_event_loop()
** : 得到當前上下文的事件循環。 - **
loop.call_later(time_delay, callback, arg)
** : 延后 time_delay 秒再執行 callback 方法。 - **
loop.call_soon(callback, argument)
** : 盡可能快調用 callback, call_soon() 函數結束,主線程回到事件循環之后就會馬上調用 callback 。 - **
loop.time()
** : 以float類型返回當前事件循環的內部時間。 - **
asyncio.set_event_loop()
** : 為當前上下文設置事件循環。 - **
asyncio.new_event_loop()
** : 根據此策略創建一個新的事件循環并返回。 - **
loop.run_forever()
**: 在調用 stop() 之前將一直運行。
3. 如何做…
下面的代碼中,我們將展示如何使用Asyncio庫提供的事件循環創建異步模式的應用。
import asyncio
import datetime
import time
def function_1(end_time, loop):
print("function_1 called")
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_2, end_time, loop)
else:
loop.stop()
def function_2(end_time, loop):
print("function_2 called ")
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_3, end_time, loop)
else:
loop.stop()
def function_3(end_time, loop):
print("function_3 called")
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_1, end_time, loop)
else:
loop.stop()
def function_4(end_time, loop):
print("function_5 called")
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_4, end_time, loop)
else:
loop.stop()
loop = asyncio.get_event_loop()
end_loop = loop.time() + 9.0
loop.call_soon(function_1, end_loop, loop)
# loop.call_soon(function_4, end_loop, loop)
loop.run_forever()
loop.close()
運行結果如下:
python3 event.py
function_1 called
function_2 called
function_3 called
function_1 called
function_2 called
function_3 called
function_1 called
function_2 called
function_3 called
在這個例子中,我們定義了三個異步的任務,相繼執行,入下圖所示的順序。
首先,我們要得到這個事件循環:
loop = asyncio.get_event_loop()
然后我們通過** call_soon
**方法調用了 ** function_1()
** 函數。
end_loop = loop.time() + 9.0
loop.call_soon(function_1, end_loop, loop)
讓我們來看一下 ** function_1()
** 的定義:
def function_1(end_time, loop):
print("function_1 called")
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_2, end_time, loop)
else:
loop.stop()
這個函數通過以下參數定義了應用的異步行為:
- **
end_time
** : 定義了 function_1() 可以運行的最長時間,并通過 call_later 方法傳入到 function_2() 中作為參數 - **
loop
** : 之前通過 get_event_loop() 方法得到的事件循環。
** function_1()
** 的任務非常簡單,只是打印出函數名字。當然,里面也可以寫非常復雜的操作。
print("function_1 called")
任務執行結束之后,它將會比較 ** loop.time()
** **+1s 和設定的運行時間,如果沒有超過,使用call_later
**在1秒之后執行 ** function_2()
**
if (loop.time() + 1.0) < end_time:
loop.call_later(1, function_2, end_time, loop)
else:
loop.stop()
其中**function_2()
**和 ****function_3()
**** 的作用類似。如果運行的時間超過了設定,事件循環終止。
loop.run_forever()
loop.close()
-
模塊
+關注
關注
7文章
2695瀏覽量
47433 -
程序
+關注
關注
117文章
3785瀏覽量
81005 -
代碼
+關注
關注
30文章
4779瀏覽量
68525 -
python
+關注
關注
56文章
4792瀏覽量
84628
發布評論請先 登錄
相關推薦
評論