我是如何學習寫一個作業系統(五):故事的高潮之進程和執行緒1
- 2019 年 10 月 3 日
- 筆記
前言
為什麼取這個標題呢?一是進程和執行緒是作為作業系統里最重要最核心的一部分。二是確實吃冰棍拉冰棍,沒話,強行湊標題和之前的標題差不多字數。
前一章寫了系統調用的過程,算是一個小插曲,這個部分不管在哪裡應該都是可以的。
現在的這個系列已經和之前的標題漸行漸遠了,原本是想以之前寫的一個玩具型作業系統FragileOS為主線,但是在看書學習的過程中稍微改了一下方向,已經不是特別關注一個作業系統的實現的完整流程和內部的聯繫,更多的是想系統的學習作業系統的各個模組然後輔以一些程式碼,但是不管怎麼樣,都是屬於自己在學習作業系統的過程的一個記錄
進入正題
進程
進程的出現最最主要的原因就是想要提高CPU的利用率
進程的定義
- 正在執行的程式
- 正在電腦上執行的程式實例
- 能夠分配給處理器並由處理器執行的實體
- 一組指令的執行、一個當前狀態和相關的系統資源的集合
多進程的組織
單核CPU在同一時刻只能運行一條指令,所謂的多進程只是指令來回切換的假象,但是因為速度太快,就可以看成是同時進行的。所以在進程切換的時就需要去組織進程的切換
進程式控制制塊(process control block)
控制進程的切換一個重要的數據結構就是進程式控制制塊(process control block),是與每個進程相關的還有作業系統用於控制進程的許多屬性的集合
進程式控制制塊的作用,是使一個在多道程式環境下不能獨立進行的程式(含數據),成為一個能獨立運行的基本單位,一個能與其他進程並發執行的進程。或者說,作業系統是根據PCB來對並發執行的進程進行控制和管理。
一般情況下,PCB中包含以下內容:
- 進程標識符(內部,外部)
- 處理機的資訊(通用暫存器,指令計數器,PSW,用戶的棧指針)。
- 進程調度資訊(進程狀態,進程的優先順序,進程調度所需的其它資訊,事件)
- 進程式控制制資訊(程式的數據的地址,資源清單,進程同步和通訊機制,鏈接指針)
進程的五狀態模型

進程的調度
一般來說,可能讓進程發生切換有這幾種事件:

但是隨著PC的發展,這種從兩方面情況發生了變化。第一,大多數時間都只有一個活躍的進程。畢竟一般來說,你在使用Word編輯文件時,不太可能還同時讓系統在後台編譯程式。這樣的情況下,調度器其實不需要做很多工作來決定到底運行哪個進程——Word幾乎就是唯一的選擇。第二,電腦的速度越來越快,以至於CPU可能已經不再那麼稀缺了。對於很多PC的程式來說,其限制主要在於用戶能進行輸入的比例,而不是CPU能夠處理的比例。甚至就算是兩個程式真的同時進行,其實先調度哪個運行也無傷大雅,例如,一個Word和一個Excel同時在運行,先調度哪個都行,因為用戶可能同時在等待這兩個程式的輸出。
但是對於網路伺服器來說,這種情況又不一樣了。非常多的程式競爭CPU資源,因此,調度又變得非常重要了。舉例來說,調度器需要決定到底是讓日常統計進程運行還是讓響應用戶請求的進程運行。
調度器除了需要考慮選擇哪個進程運行,還需要考慮到系統的性能。畢竟,進程之間的切換是開銷很大的,這涉及到從用戶態到內核狀態的切換,進程狀態的保存、恢復等等操作。
進程的同步和合作
記憶體管理
在進程進行來回切換如何保證當前進程的運行不會影響其它進程的運行,比如對於一個記憶體進程的讀寫,就要保證不能越界
所以就需要一個機制來把進程之間的地址空間隔離開

進程的同步
不同進程間存在著不同的相互制約關係。為了協調進程之間的相互制約關係,達到資源共享和進程協作,避免進程之間的衝突,就需要進程同步的概念。
多個進程可以共享系統中的各種資源,但其中許多資源一次只能為一個進程所使用,我們把一次只允許一個進程使用的資源成為臨界資源。
對臨界資源的訪問,必須互斥的進行。每個進程中,訪問臨界資源的那段程式碼成為臨界區。
為了保證臨界資源的正確使用,可以把臨界資源的訪問過程分為四個部分。
- 進入區。為了進入臨界區使用臨界資源,在進入去要檢查可否進入臨界區。
- 臨界區。進程中訪問臨界資源的那段程式碼。
- 退出區。將正在訪問臨界區的標誌清除。
- 剩餘區。程式碼中的其餘部分。
一般實現進程的同步有這幾種方法:
- 提過硬體提供的實現
- 訊號量
- 管程
執行緒
進程是資源分配的最小單位,執行緒是CPU調度的最小單位
在進程的切換時還需要對記憶體資源的一個切換,但是執行緒則不需要對資源的切換,所以引入是為了減小程式在並發執行時所付出的時空開銷,提高作業系統的並發性能。
用戶級執行緒和內核級執行緒
用戶級執行緒是指不需要內核支援而在用戶程式中實現的執行緒,內核對執行緒包一無所知。從內核角度考慮,就是按正常的方式管理,即單執行緒進程,但是它不能像內核級執行緒一樣更好的運用多核CPU。
內核級執行緒建立和銷毀都是由作業系統負責、通過系統調用完成的。在內核的支援下運行,無論是用戶進程的執行緒,或者是系統進程的執行緒,他們的創建、撤銷、切換都是依靠內核實現的。
試想一下如果沒有內核級執行緒,當用戶級的一個執行緒進行到I/O阻塞時,將會導致所有的執行緒都堵塞,因為以作業系統的層面來看,它們都屬於用一個進程,所以會直接切換進程,其它的執行緒就得不到執行
在多處理器系統中,內核級執行緒能夠真正的實現並行,能夠執行同一進程內的多個執行緒


小結
這一篇主要是簡略的總結書上的一些概念,沒有乾貨,在後面進行程式碼實現的時候會再深入的去看。下一篇可能會去看Linux0.12在進程上面的實現。