Python的Asyncio模塊提供了管理事件、協(xié)程、任務(wù)和線程的方法,以及編寫并發(fā)代碼的原語。此模塊的主要組件和概念包括:
- 事件循環(huán) : 在Asyncio模塊中,每一個進程都有一個事件循環(huán)。
- 協(xié)程 : 這是子程序的泛化概念。協(xié)程可以在執(zhí)行期間暫停,這樣就可以等待外部的處理(例如IO)完成之后,從之前暫停的地方恢復(fù)執(zhí)行。
- Futures : 定義了
Future
對象,和concurrent.futures
模塊一樣,表示尚未完成的計算。 - Tasks : 這是Asyncio的子類,用于封裝和管理并行模式下的協(xié)程。
本節(jié)中重點討論事件,事實上,異步編程的上下文中,事件無比重要。因為事件的本質(zhì)就是異步。
1. 什么是事件循環(huán)
在計算系統(tǒng)中,可以產(chǎn)生事件的實體叫做事件源,能處理事件的實體叫做事件處理者。
此外,還有一些第三方實體叫做事件循環(huán)。它的作用是管理所有的事件,在整個程序運行過程中不斷循環(huán)執(zhí)行,追蹤事件發(fā)生的順序?qū)⑺鼈兎诺疥犃兄?,當主線程空閑的時候,調(diào)用相應(yīng)的事件處理者處理事件。
最后,我們可以通過下面的偽代碼來理解事件循環(huán):
while(1) {
events = getEvents();
for (e in events)
processEvent(e);
}
所有的事件都在 ** while
**循環(huán)中捕捉,然后經(jīng)過事件處理者處理。事件處理的部分是系統(tǒng)唯一活躍的部分,當一個事件處理完成,流程繼續(xù)處理下一個事件。
2. 準備工作
Asyncio提供了以下方法來管理事件循環(huán):
- **
loop = get_event_loop()
** : 得到當前上下文的事件循環(huán)。 - **
loop.call_later(time_delay, callback, arg)
** : 延后 time_delay 秒再執(zhí)行 callback 方法。 - **
loop.call_soon(callback, argument)
** : 盡可能快調(diào)用 callback, call_soon() 函數(shù)結(jié)束,主線程回到事件循環(huán)之后就會馬上調(diào)用 callback 。 - **
loop.time()
** : 以float類型返回當前事件循環(huán)的內(nèi)部時間。 - **
asyncio.set_event_loop()
** : 為當前上下文設(shè)置事件循環(huán)。 - **
asyncio.new_event_loop()
** : 根據(jù)此策略創(chuàng)建一個新的事件循環(huán)并返回。 - **
loop.run_forever()
**: 在調(diào)用 stop() 之前將一直運行。
3. 如何做…
下面的代碼中,我們將展示如何使用Asyncio庫提供的事件循環(huán)創(chuàng)建異步模式的應(yīng)用。
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()
運行結(jié)果如下:
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
在這個例子中,我們定義了三個異步的任務(wù),相繼執(zhí)行,入下圖所示的順序。
首先,我們要得到這個事件循環(huán):
loop = asyncio.get_event_loop()
然后我們通過** call_soon
**方法調(diào)用了 ** function_1()
** 函數(shù)。
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()
這個函數(shù)通過以下參數(shù)定義了應(yīng)用的異步行為:
- **
end_time
** : 定義了 function_1() 可以運行的最長時間,并通過 call_later 方法傳入到 function_2() 中作為參數(shù) - **
loop
** : 之前通過 get_event_loop() 方法得到的事件循環(huán)。
** function_1()
** 的任務(wù)非常簡單,只是打印出函數(shù)名字。當然,里面也可以寫非常復(fù)雜的操作。
print("function_1 called")
任務(wù)執(zhí)行結(jié)束之后,它將會比較 ** loop.time()
** **+1s 和設(shè)定的運行時間,如果沒有超過,使用call_later
**在1秒之后執(zhí)行 ** 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()
**** 的作用類似。如果運行的時間超過了設(shè)定,事件循環(huán)終止。
loop.run_forever()
loop.close()
-
模塊
+關(guān)注
關(guān)注
7文章
2655瀏覽量
47293 -
程序
+關(guān)注
關(guān)注
116文章
3762瀏覽量
80754 -
代碼
+關(guān)注
關(guān)注
30文章
4723瀏覽量
68236 -
python
+關(guān)注
關(guān)注
55文章
4768瀏覽量
84376
發(fā)布評論請先 登錄
相關(guān)推薦
評論