深入理解作業系統中程式與執行緒的區別及切換機制(下)

努力的小雨發表於2023-08-29

前言

上一篇文章中我們瞭解了程式的執行方式,包括早期單核處理器上的順序執行以及引入多工概念實現的偽並行。我們還探討了程式的狀態模型。程式可以處於就緒、執行、阻塞和結束等不同的狀態。
在本篇文章中,我將探討研究程式的狀態模型、控制結構和切換機制。希望透過這篇文章的分享,能夠幫助更多的人理解和掌握程式管理的知識,為他們在計算機領域的學習和工作提供幫助。

程式的控制結構

也可以說是資料結構,畢竟作業系統也是一個程式,只要是應用程式就必然符合一條定律:程式=演算法+資料結構,程式作為一種抽象概念,可將其視為一個容器,該容器聚集了相關資源,包括地址空間,執行緒,開啟的檔案,保護許可等。因此對於單個程式,可以基於一種資料結構來表示它,這種資料結構稱之為程式控制塊(PCB),這人家的專有名詞;

每個程式都有一個唯一的PCB作為其標識,當程式被銷燬時,PCB也會隨之消失。如下:

image

PCB之間透過連結串列連線,形成各種佇列,如就緒佇列和阻塞佇列。比如:

  1. 就緒佇列:把所有就緒狀態的PCB鏈在一起;
  2. 阻塞佇列:把所有因等待某事件而處於等待狀態的程式鏈在一起

另外,在單核CPU系統中,只有一個執行指標,因為在某個時刻,只能執行一個程式。

image

程式的切換

程式的切換是為了保證每個程式都能獲得公平的CPU時間片來執行自己的程式,這也叫做上下文切換,上下文切換涉及以下內容:

  1. 儲存程式的相關資訊,如計數器、暫存器等,以便在切換回來時能正常載入。
  2. 更新程式的狀態,如從執行態切換到就緒態等。
  3. 將當前程式放入就緒佇列或阻塞佇列中。
  4. 根據排程演算法從就緒佇列中選擇一個程式載入並執行。
  5. 更新記憶體管理的資料結構(建立虛擬記憶體與實體記憶體的關係)。
  6. 新程式將自己的堆疊資訊載入到CPU的計數器和暫存器中,佔用時間片。

發生程式上下文切換有哪些場景?

時間片用完,強制進行上下文切換。

記憶體不足,將無用的程式交換出去掛起,待資源充足後再切換回來。

程式呼叫sleep函式進入睡眠狀態,讓出CPU,需要重新進行系統排程(對於執行緒也適用)。

有更高優先順序的程式需要執行,當前程式需要讓出CPU,確保高優先順序程式能使用時間片。

發生硬體中斷時,CPU立即處理相關中斷服務程式,如鍵盤輸入。即使是單核CPU,也能良好處理中斷程式和程式之間的時間片佔用。不必擔心持續敲擊鍵盤會導致系統崩潰,尤其現在大多數是多核處理器。

執行緒

在早期的作業系統中,以程式作為獨立執行的基本單位,直到後來電腦科學家們提出了更小的能獨立執行的基本單位,即執行緒。

程是程式中的一條執行流程,多個執行緒可以共享程式碼段、資料段、開啟的檔案等資源,但每個執行緒都有一套獨立的暫存器和棧,確保執行緒的控制流是相對獨立的。可以將執行緒視為CPU排程的基本單位。可以想象一個我們的Java多執行緒,程式碼公用、全域性變數公用等,但是程式會控制好執行緒自己的獨立棧資訊等;

image

執行緒的上下文切換

執行緒與程式最大的區別在於:執行緒是排程的基本單位,而程式則是資源擁有的基本單位。

執行緒的上下文切換是指在切換執行緒時,需要儲存和恢復執行緒的執行上下文。與程式相比,執行緒上下文切換的代價要小得多。

如果一個程式只有主執行緒,那麼執行緒的切換流程與程式切換相同。

如果是程式內的某個執行緒進行切換,代價會更小。只需要儲存執行緒的相關暫存器和計數器等資訊,因為其他資源和虛擬記憶體是程式內共享的,無需切換。因此,執行緒的上下文切換開銷較程式小很多。

總結

程式和執行緒是作業系統中的兩個重要概念。程式是程式的一次執行過程,擁有自己的地址空間和資源,是資源分配的基本單位。程式之間透過上下文切換來共享CPU,保證公平分配。程式切換涉及到儲存和載入程式的相關資訊、狀態變更、佇列操作、排程演算法等。

執行緒是程式中的獨立執行流程,可以共享程式的資源,但有獨立的暫存器和棧。執行緒的上下文切換相比程式較小,只需要儲存執行緒的相關暫存器和計數器等資訊。

相關文章