前言
今天我們來聊聊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等待。
今天的分享就到這了,如果我的文章對你有幫助,別忘了點贊,收藏,轉發,這對我有很大的幫助,我們下期再見~