日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python协成_Python协程(上)

發(fā)布時(shí)間:2025/3/12 python 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python协成_Python协程(上) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

幾個(gè)概念:

event_loop 事件循環(huán):程序開啟一個(gè)無限的循環(huán),程序員會(huì)把一些函數(shù)注冊到事件循環(huán)上。當(dāng)滿足事件發(fā)生的時(shí)候,調(diào)用相應(yīng)的協(xié)程函數(shù)。

coroutine 協(xié)程:協(xié)程對象,指一個(gè)使用async關(guān)鍵字定義的函數(shù),它的調(diào)用不會(huì)立即執(zhí)行函數(shù),而是會(huì)返回一個(gè)協(xié)程對象。協(xié)程對象需要注冊到事件循環(huán),由事件循環(huán)調(diào)用。

task 任務(wù):一個(gè)協(xié)程對象就是一個(gè)原生可以掛起的函數(shù),任務(wù)則是對協(xié)程進(jìn)一步封裝,其中包含任務(wù)的各種狀態(tài)。

future: 代表將來執(zhí)行或沒有執(zhí)行的任務(wù)的結(jié)果。它和task上沒有本質(zhì)的區(qū)別

async/await 關(guān)鍵字:python3.5 用于定義協(xié)程的關(guān)鍵字,async定義一個(gè)協(xié)程,await用于掛起阻塞的異步調(diào)用接口。

定義協(xié)程

通過async關(guān)鍵字定義一個(gè)協(xié)程(coroutine),協(xié)程也是一種對象。協(xié)程不能直接運(yùn)行,需要把協(xié)程加入到事件循環(huán)(loop),由后者在適當(dāng)?shù)臅r(shí)候調(diào)用協(xié)程。asyncio.get_event_loop方法可以創(chuàng)建一個(gè)事件循環(huán),然后使用run_until_complete將協(xié)程注冊到事件循環(huán),并啟動(dòng)事件循環(huán)。

import time

import asyncio

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

start = time.time()

coroutine = task(2)

loop = asyncio.get_event_loop()

loop.run_until_complete(coroutine)

print('用時(shí):', time.time()-start)

創(chuàng)建task

協(xié)程對象不能直接運(yùn)行,在注冊事件循環(huán)的時(shí)候,其實(shí)是run_until_complete方法將協(xié)程包裝成為了一個(gè)任務(wù)(task)對象。所謂task對象是Future類的子類。保存了協(xié)程運(yùn)行后的狀態(tài),用于未來獲取協(xié)程的結(jié)果。

import asyncio

import time

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

start = time.time()

coroutine = task(2)

loop = asyncio.get_event_loop()

task = loop.create_task(coroutine) # task = asyncio.ensure_future(coroutine)

print(task)

loop.run_until_complete(task)

print(task)

print('用時(shí):', time.time() - start)

創(chuàng)建task后,task在加入事件循環(huán)之前是pending狀態(tài),執(zhí)行之后是finished狀態(tài)。

asyncio.ensure_future(coroutine) 和loop.create_task(coroutine)

都可以創(chuàng)建一個(gè)task,run_until_complete的參數(shù)是一個(gè)futrue對象。當(dāng)傳入一個(gè)協(xié)程,其內(nèi)部會(huì)自動(dòng)封裝成task,task是Future的子類。isinstance(task, asyncio.Future)將會(huì)輸出True。

綁定回調(diào)

綁定回調(diào),在task執(zhí)行完畢的時(shí)候可以獲取執(zhí)行的結(jié)果,回調(diào)的最后一個(gè)參數(shù)是future對象,通過該對象可以獲取協(xié)程返回值。如果回調(diào)需要多個(gè)參數(shù),可以通過偏函數(shù)導(dǎo)入。

import time

import asyncio

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

return 'Done after {}s'.format(x)

def callback(future):

print('Callback: ', future.result())

coroutine = task(2)

loop = asyncio.get_event_loop()

task = asyncio.ensure_future(coroutine)

task.add_done_callback(callback)

loop.run_until_complete(task)

coroutine執(zhí)行結(jié)束時(shí)候會(huì)調(diào)用回調(diào)函數(shù)。并通過參數(shù)future獲取協(xié)程執(zhí)行的結(jié)果。我們創(chuàng)建的task和回調(diào)里的future對象,實(shí)際上是同一個(gè)對象。

future 與 result

回調(diào)中我們使用了future對象的result方法。前面不綁定回調(diào)的例子中,我們可以看到task有fiinished狀態(tài)。在那個(gè)時(shí)候,可以直接讀取task的result方法。

async def task(x):

print('Waiting {}'.format(x))

return 'Done after {}s'.format(x)

coroutine = task(2)

loop = asyncio.get_event_loop()

task = asyncio.ensure_future(coroutine)

loop.run_until_complete(task)

# task.result()是協(xié)程對象的返回值

print('Task result: {}'.format(task.result()))

阻塞和await

使用async可以定義協(xié)程對象,使用await可以針對耗時(shí)的操作進(jìn)行掛起,就像生成器里的yield一樣,函數(shù)讓出控制權(quán)。協(xié)程遇到await,事件循環(huán)將會(huì)掛起該協(xié)程,執(zhí)行別的協(xié)程,直到其他的協(xié)程也掛起或者執(zhí)行完畢,再進(jìn)行下一個(gè)協(xié)程的執(zhí)行。

耗時(shí)的操作一般是一些IO操作,例如網(wǎng)絡(luò)請求,文件讀取等。我們使用asyncio.sleep函數(shù)來模擬IO操作。協(xié)程的目的也是讓這些IO操作異步化。

import asyncio

import time

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

return 'Done after {}s'.format(x)

start = time.time()

coroutine = task(2)

loop = asyncio.get_event_loop()

task = asyncio.ensure_future(coroutine)

loop.run_until_complete(task)

print('Task result: ', task.result())

print('Time: ', time.time() - start)

在 sleep的時(shí)候,使用await讓出控制權(quán)。即當(dāng)遇到阻塞調(diào)用的函數(shù)的時(shí)候,使用await方法將協(xié)程的控制權(quán)讓出,以便loop調(diào)用其他的協(xié)程。現(xiàn)在我們的例子就用耗時(shí)的阻塞操作了。

并發(fā)和并行

asyncio實(shí)現(xiàn)并發(fā),就需要多個(gè)協(xié)程來完成任務(wù),每當(dāng)有任務(wù)阻塞的時(shí)候就await,然后其他協(xié)程繼續(xù)工作。創(chuàng)建多個(gè)協(xié)程的列表,然后將這些協(xié)程注冊到事件循環(huán)中。

import asyncio

import time

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

return 'Done after {}s'.format(x)

start = time.time()

coroutine1 = task(1) #

coroutine2 = task(2)

coroutine3 = task(4)

loop = asyncio.get_event_loop()

tasks = [ # 創(chuàng)建任務(wù)

asyncio.ensure_future(coroutine1),

asyncio.ensure_future(coroutine2),

asyncio.ensure_future(coroutine3)

]

loop.run_until_complete(asyncio.wait(tasks))

for task in tasks:

print('Task result: ', task.result())

print('Time: ', time.time() - start)

# 當(dāng)任務(wù)比較多的時(shí)候,可以使用列表生成式,效果是一樣的。

import asyncio

import time

async def task(x):

print('Waiting: ', x)

await asyncio.sleep(x)

return 'Done after {}s'.format(x)

start = time.time()

loop = asyncio.get_event_loop()

tasks = [asyncio.ensure_future(task(i)) for i in [1,2,4]]

loop.run_until_complete(asyncio.wait(tasks))

for task in tasks:

print('Task result: ', task.result())

print('Time: ', time.time() - start)

使用aysncio實(shí)現(xiàn)了并發(fā)。asyncio.wait(tasks) 也可以使用 asyncio.gather(*tasks) ,前者接受一個(gè)task列表,后者接收一堆task。

總結(jié)

以上是生活随笔為你收集整理的python协成_Python协程(上)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。