asyncio
是Python 3.4版本引入的標準庫,直接內置了對異步IO的支持。python
asyncio
的編程模型就是一個消息循環。咱們從asyncio
模塊中直接獲取一個EventLoop
的引用,而後把須要執行的協程扔到EventLoop
中執行,就實現了異步IO。web
用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 事件循環:程序開啓一個無限循環,把一些函數註冊到事件循環上,當知足事件發生的時候,調用相應的協程函數async
coroutine 協程:協程對象,指一個使用async關鍵字定義的函數,它的調用不會當即執行函數,而是會返回一個協程對象。協程對象須要註冊到事件循環,由事件循環調用。函數
task 任務:一個協程對象就是一個原生能夠掛起的函數,任務則是對協程進一步封裝,其中包含了任務的各類狀態oop
future: 表明未來執行或沒有執行的任務的結果。它和task上沒有本質上的區別spa
async/await 關鍵字:python3.5用於定義協程的關鍵字,async定義一個協程,await用於掛起阻塞的異步調用接口。code
一個最基本的示例:server
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)
備註:
一、咱們經過async關鍵字定義一個協程(coroutine),固然這個協程不能直接運行,須要將協程加入到事件循環loop中
二、asyncio.get_event_loop:建立一個事件循環,而後使用run_until_complete將協程註冊到事件循環,並啓動事件循環
協程對象註冊到事件循環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
完成