標籤:htm 推薦 article async 預設 main 一個棧 net 地址
進程、線程和協程的調度和運行原理總結。
進程、線程的調度策略介紹
linux的作業系統詳細調度策略可參考:http://blog.csdn.net/gatieme/article/details/51872659
linux中的進程主要有三種調度策略:
優先順序調度:將進程分為普通進程和即時進程;
先進先出(隊列)調度:即時進程先建立的先執行,直到
輪轉調度(時間片):達到一定的CPU執行時間後強制切換;
多進程程式的調度其實還是線程的調度,線程才是CPU調度的基本單位;在同一個進程內線程切換不會產生進程切換,由一個進程內的線程切換到另一個進程內的線程時,將會引起進程切換。
引起進程or線程調度的原因
linux下python進程or線程調度
如果我們使用python建立了多進程或多線程,可以認為這幾個進程或線程是在公平隊列(即優先順序相同)的即時進程,那麼其調度策略是FIFO和RR。
舉個例子,假設現在有一個單核的CPU,python程式建立了5個線程,這五個線程會安建立的時間先後進入到一個公平隊列中,CPU按先進先出原則開始執行第一個線程,如果遇到IO操作或休眠,或者執行這個線程的時間超過10ms;CUP就會停止當前線程,調到第二個線程執行直到第五個線程;然後又從第一個線程開始迴圈,直到所有的線程執行完畢資源被作業系統回收。
當然,切換進程或線程也需要付出代價的,進程切換的代價大於線程。
進程、線程和協程的資源比較
進程:
線程:
協程:
協程可以看做輕量級的線程,即協程是線上程下開啟,多協程在單線程下實現並發,而作業系統最多隻能感知到線程,也就是說協程的切換對於作業系統來說是無感知的,屬於程式層級的切換;
多個協程共用單線程的程式碼片段、公有資料(堆)等;
每個協程擁有自己的棧來儲存上下文狀態,協程的切換開銷更小,對作業系統來說,會認為一個開啟了多協程的線程一直在計算;
協程的優勢在於切換的代價更小,因此CPU的有效利用率得到了提高。
python的協程主流通過gevent和asyncio模組實現,它們的核心原理都是底層用代碼建立事件迴圈來對多個協程的上下文進行調度;
進程、線程和協程的應用情境
from redis import StrictRedisrs = StrictRedis(host=‘192.168.1.20‘, port=6390, db=1)def get_rs1(): t = time.time() res = gevent.joinall([gevent.spawn(lambda x: gevent.sleep(2), x=i) for i in range(2)]) ls = [x.get() if x.kwargs[‘x‘] == 1 else x.get() for x in res] print(ls) print(time.time() - t)if __name__ == ‘__main__‘: get_rs1()# gevent需要判斷返回的結果的順序
python之進程、線程、協程的調度原理