Python非同步程式設計2 協程任務的排程

2021-08-05 22:11:08 字數 1362 閱讀 3858

我們知道協程是非同步進行的,碰到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是不會中斷當前任務的,而是等這個任務碰到了阻塞才會處理這個事件,所以程式設計時需要把任務分的很細,盡量不要讓任務執行過長的時間。

<<

非同步程式設計 協程

現在是 python3.5 以後已經進入非同步時代 python由於gil 全域性鎖 的存在,不能發揮多核的優勢,其效能一直飽受詬病。然而在io密集型的網路程式設計裡,非同步處理比同步處理能提公升成百上千倍的效率,彌補了python效能方面的短板.現有的python 非同步框架 python 中的主...

非同步程式設計 協程

現在是 python3.5 以後已經進入非同步時代 python由於gil 全域性鎖 的存在,不能發揮多核的優勢,其效能一直飽受詬病。然而在io密集型的網路程式設計裡,非同步處理比同步處理能提公升成百上千倍的效率,彌補了python效能方面的短板.現有的python 非同步框架 python 中的主...

python協程與非同步協程

在前面幾個部落格中我們一一對應解決了消費者消費的速度跟不上生產者,浪費我們大量的時間去等待的問題,在這裡,針對業務邏輯比較耗時間的問題,我們還有除了多程序之外更優的解決方式,那就是協程和非同步協程。在引入這個概念之前我們先看 看這個圖 從這個我們可以看出來,假如來了9個任務,即使我們開了多程序,在業...