事件驅動程式


事件驅動程式側重於事件。 最終,程式的流程取決於事件。 到目前為止,我們正在處理順序或並行執行模型,但具有事件驅動程式設計概念的模型稱為非同步模型。 事件驅動的程式設計依賴於一直監聽新來的事件的事件迴圈。 事件驅動程式設計的工作取決於事件。 一旦事件迴圈,事件就決定執行什麼以及按什麼順序執行。 以下流程圖將幫助您了解其工作原理 -

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.Futureconcurrent.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.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 - 這是實現通過一組單向管道與子進程通訊的協定的基礎類別。