協(xié)程的函數(shù)python 協(xié)程的原理

Python協(xié)程之a(chǎn)syncio

asyncio 是 Python 中的異步IO庫,用來編寫并發(fā)協(xié)程,適用于IO阻塞且需要大量并發(fā)的場景,例如爬蟲、文件讀寫。

成都創(chuàng)新互聯(lián)公司專注于岷縣企業(yè)網(wǎng)站建設,響應式網(wǎng)站開發(fā),商城網(wǎng)站建設。岷縣網(wǎng)站建設公司,為岷縣等地區(qū)提供建站服務。全流程按需求定制網(wǎng)站,專業(yè)設計,全程項目跟蹤,成都創(chuàng)新互聯(lián)公司專業(yè)和態(tài)度為您提供的服務

asyncio 在 Python3.4 被引入,經(jīng)過幾個版本的迭代,特性、語法糖均有了不同程度的改進,這也使得不同版本的 Python 在 asyncio 的用法上各不相同,顯得有些雜亂,以前使用的時候也是本著能用就行的原則,在寫法上走了一些彎路,現(xiàn)在對 Python3.7+ 和 Python3.6 中 asyncio 的用法做一個梳理,以便以后能更好的使用。

協(xié)程,又稱微線程,它不被操作系統(tǒng)內(nèi)核所管理,而完全是由程序控制,協(xié)程切換花銷小,因而有更高的性能。

協(xié)程可以比作子程序,不同的是,執(zhí)行過程中協(xié)程可以掛起當前狀態(tài),轉(zhuǎn)而執(zhí)行其他協(xié)程,在適當?shù)臅r候返回來接著執(zhí)行,協(xié)程間的切換不需要涉及任何系統(tǒng)調(diào)用或任何阻塞調(diào)用,完全由協(xié)程調(diào)度器進行調(diào)度。

Python 中以 asyncio 為依賴,使用 async/await 語法進行協(xié)程的創(chuàng)建和使用,如下 async 語法創(chuàng)建一個協(xié)程函數(shù):

在協(xié)程中除了普通函數(shù)的功能外最主要的作用就是:使用 await 語法等待另一個協(xié)程結(jié)束,這將掛起當前協(xié)程,直到另一個協(xié)程產(chǎn)生結(jié)果再繼續(xù)執(zhí)行:

asyncio.sleep() 是 asyncio 包內(nèi)置的協(xié)程函數(shù),這里模擬耗時的IO操作,上面這個協(xié)程執(zhí)行到這一句會掛起當前協(xié)程而去執(zhí)行其他協(xié)程,直到sleep結(jié)束,當有多個協(xié)程任務時,這種切換會讓它們的IO操作并行處理。

注意,執(zhí)行一個協(xié)程函數(shù)并不會真正的運行它,而是會返回一個協(xié)程對象,要使協(xié)程真正的運行,需要將它們加入到事件循環(huán)中運行,官方建議 asyncio 程序應當有一個主入口協(xié)程,用來管理所有其他的協(xié)程任務:

在 Python3.7+ 中,運行這個 asyncio 程序只需要一句: asyncio.run(main()) ,而在 Python3.6 中,需要手動獲取事件循環(huán)并加入?yún)f(xié)程任務:

事件循環(huán)就是一個循環(huán)隊列,對其中的協(xié)程進行調(diào)度執(zhí)行,當把一個協(xié)程加入循環(huán),這個協(xié)程創(chuàng)建的其他協(xié)程都會自動加入到當前事件循環(huán)中。

其實協(xié)程對象也不是直接運行,而是被封裝成一個個待執(zhí)行的 Task ,大多數(shù)情況下 asyncio 會幫我們進行封裝,我們也可以提前自行封裝 Task 來獲得對協(xié)程更多的控制權(quán),注意,封裝 Task 需要 當前線程有正在運行的事件循環(huán) ,否則將引 RuntimeError,這也就是官方建議使用主入口協(xié)程的原因,如果在主入口協(xié)程之外創(chuàng)建任務就需要先手動獲取事件循環(huán)然后使用底層方法 loop.create_task() ,而在主入口協(xié)程之內(nèi)是一定有正在運行的循環(huán)的。任務創(chuàng)建后便有了狀態(tài),可以查看運行情況,查看結(jié)果,取消任務等:

asyncio.create_task() 是 Python3.7 加入的高層級API,在 Python3.6,需要使用低層級API asyncio.ensure_future() 來創(chuàng)建 Future,F(xiàn)uture 也是一個管理協(xié)程運行狀態(tài)的對象,與 Task 沒有本質(zhì)上的區(qū)別。

通常,一個含有一系列并發(fā)協(xié)程的程序?qū)懛ㄈ缦拢≒ython3.7+):

并發(fā)運行多個協(xié)程任務的關鍵就是 asyncio.gather(*tasks) ,它接受多個協(xié)程任務并將它們加入到事件循環(huán),所有任務都運行完成后會返回結(jié)果列表,這里我們也沒有手動封裝 Task,因為 gather 函數(shù)會自動封裝。

并發(fā)運行還有另一個方法 asyncio.wait(tasks) ,它們的區(qū)別是:

Python異步編程4:協(xié)程函數(shù),協(xié)程對象,await關鍵字

協(xié)程函數(shù):async def?函數(shù)名。3.5+

協(xié)程對象:執(zhí)行協(xié)程函數(shù)()得到的協(xié)程對象。

3.5之后的寫法:

3.7之后的寫法:更簡便

await后面?跟?可等待的對象。(協(xié)程對象,F(xiàn)uture,Task對象?約等于IO等待)

await實例2:串行執(zhí)行。 一個協(xié)程函數(shù)里面可以支持多個await ,雖然會串行,但是如果有其他協(xié)程函數(shù),任務列表也在執(zhí)行,依然會切換。只是案例中的main對應執(zhí)行的others1和others2串行 。 await會等待對象的值得到之后才繼續(xù)往下走。

python協(xié)程(4):asyncio

asyncio是官方提供的協(xié)程的類庫,從python3.4開始支持該模塊

async awiat是python3.5中引入的關鍵字,使用async關鍵字可以將一個函數(shù)定義為協(xié)程函數(shù),使用awiat關鍵字可以在遇到IO的時候掛起當前協(xié)程(也就是任務),去執(zhí)行其他協(xié)程。

await + 可等待的對象(協(xié)程對象、Future對象、Task對象 - IO等待)

注意:在python3.4中是通過asyncio裝飾器定義協(xié)程,在python3.8中已經(jīng)移除了asyncio裝飾器。

事件循環(huán),可以把他當做是一個while循環(huán),這個while循環(huán)在周期性的運行并執(zhí)行一些協(xié)程(任務),在特定條件下終止循環(huán)。

loop = asyncio.get_event_loop():生成一個事件循環(huán)

loop.run_until_complete(任務):將任務放到事件循環(huán)

Tasks用于并發(fā)調(diào)度協(xié)程,通過asyncio.create_task(協(xié)程對象)的方式創(chuàng)建Task對象,這樣可以讓協(xié)程加入事件循環(huán)中等待被調(diào)度執(zhí)行。除了使用 asyncio.create_task() 函數(shù)以外,還可以用低層級的 loop.create_task() 或 ensure_future() 函數(shù)。不建議手動實例化 Task 對象。

本質(zhì)上是將協(xié)程對象封裝成task對象,并將協(xié)程立即加入事件循環(huán),同時追蹤協(xié)程的狀態(tài)。

注意:asyncio.create_task() 函數(shù)在 Python 3.7 中被加入。在 Python 3.7 之前,可以改用 asyncio.ensure_future() 函數(shù)。

下面結(jié)合async awiat、事件循環(huán)和Task看一個示例

示例一:

*注意:python 3.7以后增加了asyncio.run(協(xié)程對象),效果等同于loop = asyncio.get_event_loop(),loop.run_until_complete(協(xié)程對象) *

示例二:

注意:asyncio.wait 源碼內(nèi)部會對列表中的每個協(xié)程執(zhí)行ensure_future從而封裝為Task對象,所以在和wait配合使用時task_list的值為[func(),func()] 也是可以的。

示例三:

分享名稱:協(xié)程的函數(shù)python 協(xié)程的原理
文章轉(zhuǎn)載:http://muchs.cn/article34/hphepe.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供虛擬主機、商城網(wǎng)站、網(wǎng)站維護網(wǎng)站策劃、移動網(wǎng)站建設、ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營