1. 程式人生 > >asyncio的簡單了解

asyncio的簡單了解

don loop create 完成後 run n! 狀態 內部 syn

asyncio是Python 3.4版本引入的標準庫,直接內置了對異步IO的支持。

asyncio的編程模型就是一個消息循環。我們從asyncio模塊中直接獲取一個EventLoop的引用,然後把需要執行的協程扔到EventLoop中執行,就實現了異步IO。

asyncio實現Hello world代碼如下:

import asyncio

@asyncio.coroutine
def hello():
    print("Hello world!")
    # 異步調用asyncio.sleep(1):
    r = yield from asyncio.sleep(1)
    
print("Hello again!") # 獲取EventLoop: loop = asyncio.get_event_loop() # 執行coroutine loop.run_until_complete(hello()) loop.close()

關於asyncio的一些關鍵字的說明:

  • event_loop 事件循環:程序開啟一個無限循環,把一些函數註冊到事件循環上,當滿足事件發生的時候,調用相應的協程函數

  • coroutine 協程:協程對象,指一個使用async關鍵字定義的函數,它的調用不會立即執行函數,而是會返回一個協程對象。協程對象需要註冊到事件循環,由事件循環調用。

  • task 任務:一個協程對象就是一個原生可以掛起的函數,任務則是對協程進一步封裝,其中包含了任務的各種狀態

  • future: 代表將來執行或沒有執行的任務的結果。它和task上沒有本質上的區別

  • async/await 關鍵字:python3.5用於定義協程的關鍵字,async定義一個協程,await用於掛起阻塞的異步調用接口。

一個最基本的示例:

import time
import asyncio

now = lambda :time.time()

print(now)  # <function <lambda> at 0x000001F6E1E52E18>  相信部分人到這就蒙圈了吧,lambda還能這麽用
start = now() async def do_some_work(x): print("waiting:",x) coroutine = do_some_work(10) print(coroutine) # <coroutine object do_some_work at 0x000002133DEFBAF0> 一個協程對象 # 創建一個事件loop loop = asyncio.get_event_loop() # 將攜程對象加入到事件循環loop中 loop.run_until_complete(coroutine) print("Use Time:",now()-start)

  備註:

  1、我們通過async關鍵字定義一個協程(coroutine),當然這個協程不能直接運行,需要將協程加入到事件循環loop中

  2、asyncio.get_event_loop:創建一個事件循環,然後使用run_until_complete將協程註冊到事件循環,並啟動事件循環

創建Task

  協程對象註冊到事件循環loop中,是通過run_until_complete 方法實現的,其實這個run_until_complete方法內部是將協程包裝成為了一個任務(task)對象

  這個 task對象是Future類的子類,它保存了協程運行後的狀態,用來後續獲取協程的結果
示例:

import asyncio
import time


now = lambda: time.time()


async def do_some_work(x):
    print("waiting:", x)

start = now()

coroutine = do_some_work(2)
loop = asyncio.get_event_loop()
# 創建一個task對象
task = loop.create_task(coroutine)
print(task,type(task))    # <Task pending coro=<do_some_work() running at D:/webserver/unittests/async.py:8>>     <class ‘_asyncio.Task‘>
loop.run_until_complete(task)
print(task)   # <Task finished coro=<do_some_work() done, defined at D:/webserver/unittests/async.py:8> result=None>
print("Time:",now()-start)

  由此示例可見: 在task加入事件循環之前為pending狀態,當完成後,狀態為finished

擴展補充:

  上面的示例中,我們通過loop.create_task() 來創建一個task,同樣的,我們也可以使用 asyncio.ensure_future(coroutine) 來創建task

總結:

  1,異步操作需要在coroutine中通過yield from完成

asyncio的簡單了解