event_loop
(事件循環):程序開啓一個無線的循環,程序員會把一些函數(協程)註冊到事件循環上,當知足事件發生的時候,調用相應的協程函數。python
coroutine
(協程):協程對象,指一個使用async關鍵字定義的函數,它的調用不會當即執行,而是生成一個協程對象。協程對象須要註冊到事件循環,由事件循環調用。程序員
future
(對象):表明未來執行或沒有執行的任務的結果,與task沒有本質上的區別。異步
task
(任務):一個協程對象就是一個原生能夠掛起的函數,任務則是對協程的進一步封裝,其中包含任務的各類狀態,Task對象是Future的子類,它將coroutine和Future聯繫在一塊兒,將協程對象封裝成一個future對象。async
async / await
(關鍵字):python 3.5 用於定義協程的關鍵字,async定義一個協程,await用於掛起阻塞的異步調用接口,其做用在必定程度上相似於yield from函數
只要在一個生成器函數頭部使用裝飾器 @asyncio.coroutine,就標記爲協程對象。實際上,本質仍是一個生成器oop
import asyncio def hello(): yield 1 @asyncio.coroutine def hello1(): yield from asyncio.sleep(1) if __name__ == '__main__': res = hello() res1 = hello1() print(type(res)) print(type(res1))
協程的完整執行流程code
import asyncio async def hello(): print('協程的完整執行流程') print('1:建立一個協程對象') print('2:建立一個事件循環容器') print('3:將協程對象轉爲task任務') print('4:將任務註冊到事件循環中執行') # 建立一個協程對象 cor = hello() # 建立一個事件循環容器 loop = asyncio.get_event_loop() # 將協程對象轉爲task任務 # task = loop.create_task(cor) task = asyncio.ensure_future(cor) # 將任務註冊到事件循環中執行 loop.run_until_complete(task)
前面概念已經說過,await
做用與yield from
相似,都是實現暫停的效果,可是功能上卻不兼容,就是不能在生成器中使用await
,也不能在async定義的協程中使用yield from
。
協程
除此以外呢,還有一點很重要的。對象
yield from
後面跟可迭代對象,也能夠跟 future obj
、coroutine obj
await
後面必須接 future obj
、coroutine obj
驗證以前先介紹一個函數
asyncio.sleep(sec)
:這個是asyncio模塊自帶的函數,能夠模擬io阻塞。返回的是一個協程對象。blog
import asyncio # await 跟協程 async def f1(): await asyncio.sleep(1) print('await 跟協程') # yield from 跟協程 def f2(): yield from asyncio.sleep(2) print('yield from 跟協程') # await 跟 future async def f3(): await asyncio.ensure_future(asyncio.sleep(3)) print('await 接 future') # yield from 跟 future def f4(): yield from asyncio.ensure_future(asyncio.sleep(4)) print('yield from 跟 future')
異步IO的實現原理,就是在IO的地方掛起,執行其餘任務,等IO結束,再繼續執行。回調的方式實現方法有兩種。
第一種:
async def slp(t): await asyncio.sleep(t) return '暫停了 %d s' % t cor = slp(5) loop = asyncio.get_event_loop() task = loop.create_task(cor) loop.run_until_complete(task) print('返回結果:',task.result())
第二種:
async def slp(t): await asyncio.sleep(t) return '暫停了 %d s' % t def callback(future): print('這是回調函數,返回結果是:', future.result()) cor = slp(5) loop = asyncio.get_event_loop() task = loop.create_task(cor) # 爲task添加回調函數 task.add_done_callback(callback) loop.run_until_complete(task)