003.2---asyncio模塊(上)

asyncio(上)

asyncio 的幾個概念

  • 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

  • 建立一個協程對象
  • 建立一個事件循環容器
  • 將協程對象轉爲task任務
  • 將任務註冊到事件循環中執行
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做用與yield from相似,都是實現暫停的效果,可是功能上卻不兼容,就是不能在生成器中使用await,也不能在async定義的協程中使用yield from

協程

除此以外呢,還有一點很重要的。對象

  • yield from 後面跟可迭代對象,也能夠跟 future objcoroutine obj
  • await 後面必須接 future objcoroutine 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)
相關文章
相關標籤/搜索