1. 程式人生 > 程式設計 >Python非同步程式設計之協程任務的排程操作例項分析

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程式設計有所幫助。