1. 程式人生 > >我是如何學習寫一個作業系統(五):故事的高潮之程序和執行緒1

我是如何學習寫一個作業系統(五):故事的高潮之程序和執行緒1

前言

為什麼取這個標題呢?一是程序和執行緒是作為作業系統裡最重要最核心的一部分。二是確實吃冰棍拉冰棍,沒話,強行湊標題和之前的標題差不多字數。

前一章寫了系統呼叫的過程,算是一個小插曲,這個部分不管在哪裡應該都是可以的。

現在的這個系列已經和之前的標題漸行漸遠了,原本是想以之前寫的一個玩具型作業系統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在程序上面的實現