Python非同步程式設計之協程任務的排程操作例項分析
本文例項講述了Python非同步程式設計之協程任務的排程操作。分享給大家供大家參考,具體如下:
我們知道協程是非同步進行的,碰到IO阻塞型操作時需要排程其他任務,那麼這個排程規則或者是演算法是怎樣的呢?現在有以下幾個疑問:
1、多個任務準備好,需要執行時,優先執行哪一個?
2、一個任務執行時,如果別的任務準備好了,是否需要中斷當前任務呢?
在網上找了很多資料,也無法找到相關的資料,於是編寫了幾個簡單的程式,檢視任務的執行過程。
根據Python的asyncio我們可以編寫一個簡單的程式:
import asyncio async def a(x): while x>0: print('a:',x) await asyncio.sleep(0.5) x -= 1 async def b(x): while x>0: print('b:',x) await asyncio.sleep(1.8) x -= 1 async def c(x): while x>0: print('c:',x) await asyncio.sleep(1.5) x -= 1 loop = asyncio.get_event_loop() tasks = [a(2),b(2),c(2)] loop.run_until_complete(asyncio.wait(tasks)) loop.close()
我們建立一個loop事件,把a,b,c3個函式加入到任務中,用asyncio.sleep(1)來切換執行其他程式。執行結果如下:
b: 2
c: 2
a: 2
a: 1
c: 1
b: 1
這裡一直有一個疑問,開始執行任務時,3個任務同時準備好,為什麼執行順序是b,a,c。
我們分析一下函式的執行過程,先執行b,然後阻塞,執行c,阻塞,再執行a,阻塞。函式呼叫過程是b->c->a,0.5s過後a完成,1.5s過後c完成,1.8s過後b完成。
修改睡眠時間,我們可以測試出很多情況,最後得出了任務排程的規則,可能有一些地方總結的不對,歡迎大家來指正。
1、初始化,asyncio把需要執行的任務加入到任務佇列中。
2、從隊首拿出一個任務來執行,如果任務被阻塞,則拿另一個任務佇列,在任務切換是需要儲存每個任務的工作環境。
3、把IO的完成,定時時間到的時間加入到事件佇列,從隊首中拿出事件去喚醒相應的任務。
好像看起來很簡單,又有點像作業系統,又有點像中斷,但是作業系統是感知不到它的存在,更沒有呼叫中斷了。這裡我們要注意,加入有一個任務正在執行,同時有一個事件發生,asyncio是不會中斷當前任務的,而是等這個任務碰到了阻塞才會處理這個事件,所以程式設計時需要把任務分的很細,儘量不要讓任務執行過長的時間。
更多關於Python相關內容感興趣的讀者可檢視本站專題:《Python程序與執行緒操作技巧總結》、《Python資料結構與演算法教程》、《Python函式使用技巧總結》、《Python字串操作技巧彙總》、《Python入門與進階經典教程》、《Python+MySQL資料庫程式設計入門教程》及《Python常見資料庫操作技巧彙總》
希望本文所述對大家Python程式設計有所幫助。