簡單聊聊Python協程

前言

今天我們來聊聊Python協程,當Python學習到一定的深度,當你需要對代碼進行優化提速時,就避不開異步編程,尤其是現在優秀的第三方庫都實現了異步編程,這使得我們不得不學習。

本人也是最近開始學習這個概念,本次分享我們就來簡單聊聊Python協程的概念和最基本的語法。

什麼是協程

我們先來看看協程的概念。

協程(Coroutine),也可以被稱爲微線程,是一種用戶態內的上下文切換技術。

概念是不是很不好理解,沒關係,我們引入一個小學就學過的數學思考題。小明早上起牀需要刷牙和燒水,刷牙需要5分鐘,燒水需要8分鐘,問小明總共需要幾分鐘完成這兩件事情。

答案是8分鐘,這你應該是知道的吧。其實這就是協程,現在我再來解釋下,刷牙是一個函數,燒水時一個函數,那協程就是通過一個線程實現代碼塊相互切換執行。

Python實現協程

我們首先來看看不用協程怎麼來寫。

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('花費時間{}s'.format(end-start))


main()

開始刷牙
刷牙完成
開始燒水
燒水完成
花費時間13.01053786277771s

看到沒,需要13s,那我們來看看協程怎麼寫。

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('花費時間{}s'.format(end-start))


asyncio.run(main())

開始燒水
開始刷牙
刷牙完成
燒水完成
花費時間8.004523992538452s

用了協程後,程序就只需要8s了。所以協程很有用,協程一般應用在有IO操作的程序中,因爲協程可以利用IO等待的時間去執行一些其他的代碼,從而提升代碼執行效率。

代碼解釋

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

(1)asyncio.run(main()),進入main函數,事件循環開始。

這裏有必要解釋一下事件循環,事件循環可以看做成while循環,一直循環着任務,當任務完成時,纔會終止循環。

(2)tasks列表裏面就創建了兩個任務,這兩個任務就進入到了事件循環,準備執行。

這裏創建的任務就是協程對象,當用async關鍵字定義的函數就是協程函數,調用這個函數,返回的就是協程對象。

(3)await asyncio.wait(tasks)就會進入任務中,首先進入燒水任務,遇到IO(這裏是睡眠),就跳入到另外一個一個任務(刷牙),然後又遇到IO,這裏沒有其他任務了,所以等待完成刷牙任務,就跳入到燒水任務,完成後,整個事件循環就結束了。

awit關鍵詞就是等待的意思,後面接的是IO等待。

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章