簡單聊聊Python協(xié)程

前言

今天我們來聊聊Python協(xié)程,當(dāng)Python學(xué)習(xí)到一定的深度,當(dāng)你需要對代碼進(jìn)行優(yōu)化提速時(shí),就避不開異步編程,尤其是現(xiàn)在優(yōu)秀的第三方庫都實(shí)現(xiàn)了異步編程,這使得我們不得不學(xué)習(xí)。

本人也是最近開始學(xué)習(xí)這個(gè)概念,本次分享我們就來簡單聊聊Python協(xié)程的概念和最基本的語法。

什么是協(xié)程

我們先來看看協(xié)程的概念。

協(xié)程(Coroutine),也可以被稱為微線程,是一種用戶態(tài)內(nèi)的上下文切換技術(shù)。

概念是不是很不好理解,沒關(guān)系,我們引入一個(gè)小學(xué)就學(xué)過的數(shù)學(xué)思考題。小明早上起床需要刷牙和燒水,刷牙需要5分鐘,燒水需要8分鐘,問小明總共需要幾分鐘完成這兩件事情。

答案是8分鐘,這你應(yīng)該是知道的吧。其實(shí)這就是協(xié)程,現(xiàn)在我再來解釋下,刷牙是一個(gè)函數(shù),燒水時(shí)一個(gè)函數(shù),那協(xié)程就是通過一個(gè)線程實(shí)現(xiàn)代碼塊相互切換執(zhí)行。

Python實(shí)現(xiàn)協(xié)程

我們首先來看看不用協(xié)程怎么來寫。

import time


def brush_teeth():
    print('開始刷牙')
    time.sleep(5)
    print('刷牙完成')


def boil_water():
    print('開始燒水')
    time.sleep(8)
    print('燒水完成')


def main():
    start = time.time()
    brush_teeth()
    boil_water()
    end = time.time()
    print('花費(fèi)時(shí)間{}s'.format(end-start))


main()

開始刷牙
刷牙完成
開始燒水
燒水完成
花費(fèi)時(shí)間13.01053786277771s

看到?jīng)],需要13s,那我們來看看協(xié)程怎么寫。

import asyncio
import time


async def brush_teeth():
    print('開始刷牙')
    await asyncio.sleep(5)
    print('刷牙完成')


async def boil_water():
    print('開始燒水')
    await asyncio.sleep(8)
    print('燒水完成')


async def main():
    start = time.time()
    tasks = [
        asyncio.create_task(boil_water()),
        asyncio.create_task(brush_teeth())
    ]
    await asyncio.wait(tasks)
    end = time.time()
    print('花費(fèi)時(shí)間{}s'.format(end-start))


asyncio.run(main())

開始燒水
開始刷牙
刷牙完成
燒水完成
花費(fèi)時(shí)間8.004523992538452s

用了協(xié)程后,程序就只需要8s了。所以協(xié)程很有用,協(xié)程一般應(yīng)用在有IO操作的程序中,因?yàn)閰f(xié)程可以利用IO等待的時(shí)間去執(zhí)行一些其他的代碼,從而提升代碼執(zhí)行效率。

代碼解釋

最好,我們來解釋一下代碼。

(1)asyncio.run(main()),進(jìn)入main函數(shù),事件循環(huán)開始。

這里有必要解釋一下事件循環(huán),事件循環(huán)可以看做成while循環(huán),一直循環(huán)著任務(wù),當(dāng)任務(wù)完成時(shí),才會(huì)終止循環(huán)。

(2)tasks列表里面就創(chuàng)建了兩個(gè)任務(wù),這兩個(gè)任務(wù)就進(jìn)入到了事件循環(huán),準(zhǔn)備執(zhí)行。

這里創(chuàng)建的任務(wù)就是協(xié)程對象,當(dāng)用async關(guān)鍵字定義的函數(shù)就是協(xié)程函數(shù),調(diào)用這個(gè)函數(shù),返回的就是協(xié)程對象。

(3)await asyncio.wait(tasks)就會(huì)進(jìn)入任務(wù)中,首先進(jìn)入燒水任務(wù),遇到IO(這里是睡眠),就跳入到另外一個(gè)一個(gè)任務(wù)(刷牙),然后又遇到IO,這里沒有其他任務(wù)了,所以等待完成刷牙任務(wù),就跳入到燒水任務(wù),完成后,整個(gè)事件循環(huán)就結(jié)束了。

awit關(guān)鍵詞就是等待的意思,后面接的是IO等待。

今天的分享就到這了,如果我的文章對你有幫助,別忘了點(diǎn)贊,收藏,轉(zhuǎn)發(fā),這對我有很大的幫助,我們下期再見~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容