事件驅動程序
事件驅動程序側重於事件。 最終,程序的流程取決於事件。 到目前爲止,我們正在處理順序或並行執行模型,但具有事件驅動編程概念的模型稱爲異步模型。 事件驅動的編程依賴於一直監聽新來的事件的事件循環。 事件驅動編程的工作取決於事件。 一旦事件循環,事件就決定執行什麼以及按什麼順序執行。 以下流程圖將幫助您瞭解其工作原理 -
Python模塊 - Asyncio
Asyncio模塊是在Python 3.4中添加的,它提供了使用協同例程編寫單線程併發代碼的基礎結構。 以下是Asyncio模塊使用的不同概念 -
事件循環
事件循環是處理計算代碼中所有事件的功能。 它在執行整個程序的過程中一路行動,並跟蹤事件的傳入和執行。 Asyncio模塊允許每個進程使用一個事件循環。 以下是Asyncio模塊提供的用於管理事件循環的一些方法 -
-
loop = get_event_loop()
- 此方法將爲當前上下文提供事件循環。 -
loop.call_later(time_delay,callback,argument)
- 此方法安排在給定的time_delay
秒後要調用的回調。 -
loop.call_soon(callback,argument)
- 該方法安排一個儘可能快地被調用的回調函數。 回調在call_soon()
返回並且控件返回到事件循環後調用。 -
loop.time()
- 此方法用於根據事件循環的內部時鐘返回當前時間。 -
asyncio.set_event_loop()
- 此方法將設置當前上下文的事件循環爲循環。 -
asyncio.new_event_loop()
- 此方法將創建並返回一個新的事件循環對象。 -
loop.run_forever()
- 此方法將運行,直到調用stop()
方法。
例子
下面的事件循環示例通過使用get_event_loop()
方法幫助打印hello world
。 這個例子取自Python官方文檔。
import asyncio
def hello_world(loop):
print('Hello World')
loop.stop()
loop = asyncio.get_event_loop()
loop.call_soon(hello_world, loop)
loop.run_forever()
loop.close()
輸出結果如下 -
Hello World
特徵 - Future
這與表示未完成的計算的concurrent.futures.Future
類兼容。 asyncio.futures.Future
和concurrent.futures.Future
之間存在以下差異 -
-
result()
和exception()
方法不會接受超時參數,並在未來尚未完成時引發異常。 - 通過
add_done_callback()
註冊的回調函數總是通過事件循環的call_soon()
來調用。 -
asyncio.futures.Future
類與concurrent.futures
包中的wait()
和as_completed()
函數不兼容。
例子
以下演示如何使用asyncio.futures.future
類的示例。
import asyncio
async def Myoperation(future):
await asyncio.sleep(2)
future.set_result('Future Completed')
loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(Myoperation(future))
try:
loop.run_until_complete(future)
print(future.result())
finally:
loop.close()
輸出結果如下 -
Future Completed
協同程序
Asyncio中的協程的概念與線程模塊下的標準線程對象的概念類似。 這是子程序概念的一般化。 協程在執行過程中可以暫停,以等待外部處理,並在完成外部處理時從其停止點返回。 以下兩種方式可以幫助我們實施協同程序 -
async def function()
這是在Asyncio模塊下實現協程的一種方法。 以下是一個相同的Python腳本 -
import asyncio
async def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
執行上面示例代碼,得到以下結果 -
First Coroutine
@asyncio.coroutine裝飾器
另一種實現協程的方法是使用帶有[@asyncio](https://github.com/asyncio "@asyncio").coroutine
修飾器的生成器。 以下是一個相同的Python腳本 -
import asyncio
@asyncio.coroutine
def Myoperation():
print("First Coroutine")
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(Myoperation())
finally:
loop.close()
執行上面示例代碼,得到以下結果 -
First Coroutine
任務
Asyncio模塊的這個子類負責以並行方式在事件循環中執行協程。 以下Python腳本是並行處理某些任務的示例。
import asyncio
import time
async def Task_ex(n):
time.sleep(1)
print("Processing {}".format(n))
async def Generator_task():
for i in range(10):
asyncio.ensure_future(Task_ex(i))
int("Tasks Completed")
asyncio.sleep(2)
loop = asyncio.get_event_loop()
loop.run_until_complete(Generator_task())
loop.close()
執行上面示例代碼,得到以下結果 -
Tasks Completed
Processing 0
Processing 1
Processing 2
Processing 3
Processing 4
Processing 5
Processing 6
Processing 7
Processing 8
Processing 9
傳輸
Asyncio模塊提供了用於實現各種類型通信的傳輸類。 這些類不是線程安全的,並且在建立通信通道後總是與協議實例配對。
以下是從BaseTransport
繼承的不同類型的傳輸 -
-
ReadTransport
- 這是隻讀傳輸的接口。 -
WriteTransport
- 這是用於只寫傳輸的接口。 -
DatagramTransport
- 這是發送數據的接口。 -
BaseSubprocessTransport
- 與BaseTransport
類相似。
以下是BaseTransport
類的五種不同方法,它們隨後在四種BaseTransport
類有不同的變型 -
-
close()
- 關閉運輸。 -
is_closing()
- 如果傳輸正在關閉或者已經是closed.transports
,則此方法將返回true
。 -
get_extra_info(name,default = none)
- 這會給一些關於傳輸的額外信息。 -
get_protocol()
- 此方法將返回當前協議。
協議
Asyncio模塊提供了可以繼承的基類,以實現您的網絡協議。 這些類與運輸一起使用; 該協議解析傳入數據並要求寫入傳出數據,而傳輸負責實際的I/O和緩衝。 以下是三種Protocol
類 -
-
Protocol
- 這是實現用於TCP和SSL傳輸的流協議的基類。 -
DatagramProtocol
- 這是實現用於UDP傳輸的數據報協議的基類。 -
SubprocessProtocol
- 這是實現通過一組單向管道與子進程通信的協議的基類。