一、進程概念
進程是執行中的程式,形成所有計算的基礎。更完整的解釋是一個具有獨立功能的程式關於某個資料集合的一次運行活動。它可以申請和擁有系統資源,是一個動態概念,是一個活動的實體。它不只是程式的代碼,還包括當前的活動,通過程式計數器的值和處理寄存器的內容來表示。
二、進程狀態
進程有五種狀態,分別是:
新的:進程正在被建立
運行:指令正在被執行
等待:進程等待某個事件的發生(如I/O完成或收到訊號)
就緒:進程等待分配處理器
終止:進程完成執行
這五種狀態的變遷圖如下:
三、線程
線程由線程ID、程式計數器、寄存器集合和棧組成。它與屬於同一個進程的其他線程共用程式碼片段、資料區段和其他動作系統資源。
線程是CPU調度的基本單元,進程是系統資源分派的基本單元,一個進程中可能包含多個線程。
多線程編程具有響應度高、資源共用、經濟和多處理器體繫結構的利用四個優點。雖然我們使用者進程中可以有很多線程可以執行,但實際上這些使用者線程都是映射到核心線程上來執行的。使用者線程和核心線程之間的映射關聯式模式包含有:
(1)多對一
(2)一對一
(3)多對多
線程庫為程式員提供了建立和管理線程的API。主要有兩種方法來實現線程庫,一種是使用者空間的本地函數庫(非系統調用),一種是系統直接支援的核心級庫(系統調用)。目前使用的主要有三種線程庫,如下:
(1)POSIX Pthread:Linux下使用的API,有使用者級也有核心級的庫
(2)Win32:Windows下的核心級線程庫
(3)Java:使用者級的庫,Java虛擬機器通常調用宿主機上的線程庫來實現,在windows上就是採用win32 API。
四、CPU調度
我們通常說的CPU調度是講進程調度,實際上現在支援一個進程包含多線程的作業系統中CPU的調度對象都是針對的核心線程,不過調度演算法是一樣的。下面我們都用進程調度來說調度演算法。每個進程的執行都是若干個CPU區間和I/O區間組成,I/O約束程式通常具有很短的CPU區間,CPU約束程式可能有少量的長CPU區間,瞭解進程的這種分布有助於選擇合適的調度演算法。
CPU的調度決策會發生在如下四種情況下:
(1)運行-->等待
(2)運行-->就緒
(3)等待-->就緒
(4)運行-->終止
對於(1)和(4)兩種情況都是啟動並執行進程要麼是資源條件不足,要麼是運行結束了,這個時候需要選擇新的就緒隊列的進程轉入運行狀態,因此只有調度,沒有選擇;對於(2)和(3)兩種情況下則是有進程進入就緒狀態,這時可以選擇。當調度只能發生在(1)和(4)兩種情況下時,調度方案稱為非搶佔調度(新的就緒進程的出現不影響正在啟動並執行進程),否則稱為搶佔調度(新的就緒進程可能搶佔了當前運行進程的CPU資源)。
為了比較不同的調度演算法,產生了許多的調度準則,如下:
CPU使用率:需要使CPU盡量忙
輸送量:一個時間單元內所完成進程的數量
周轉時間:從進程提交到進程完成的時間段
等待時間:在就緒隊列等待所花費時間之和
回應時間:從提交請求到產生第一相應的時間
好的調度演算法都是使CPU使用率和輸送量最大化,而使周轉時間、等待時間和回應時間最小化。下面一一介紹具體的調度演算法。
1、先來先服務(FCFS)
最簡單的CPU調度演算法,根據進程進入就緒隊列的先後順序調度進程執行。但是這種方法的平均等待時間通常較長。
2、最短作業優先調度(SJF)
將每個進程與下一個CPU區間段相關聯,當CPU空閑時,他回賦給具有最短CPU區間的進程。如果兩個進程具有相同CPU區間長度,可以使用FCFS來調度。這裡的CPU區間長度是進程的下一個CPU區間長度,而不是進程的CPU區間總長度。此演算法可證明是最佳的,其痛點在於如何知道進程的下一個CPU區間的長度。近似的情況下只能通過預測來做。
3、優先順序調度
每個進程都有一個優先順序相關聯,具有最高優先順序的進程會被分配到CPU,具有相同優先順序的進程根據FCFS順序調度。實際上短作業優先就是優先順序調度演算法的一個特例。
優先順序調度演算法的一個主要問題是導致低優先順序的進程產生無窮阻塞或饑餓(可以運行但是缺乏CPU),其解決問題之一就是老化,即以逐漸增加在系統中等待很長時間的進程的優先順序。
4、時間片輪轉法調度(RR)
為分時系統而設計,類似於FCFS,不過每個進程只分配不超過一個時間片的CPU,對就緒隊列中的進程依次迴圈分配時間執行。
5、多級隊列調度
將就緒隊列中的進程根據進程的屬性不同而永久分配到多個獨立的隊列中,每個隊列都有自己的調度演算法。同時隊列中也有調度,通常採用固定優先順序搶佔調度。
6、多級反饋隊列調度
跟多級隊列調度相似,最大的不同是允許進程在隊列之間移動。主要思想是根據不同CPU區間的特點以區分進程,如果進程使用過多CPU時間,那麼它會被轉移到更低優先順序隊列。
多級反饋隊列調度是最通用的CPU調度演算法但是因為要設定很多調度參數,因此也是最複雜的演算法。
五、多處理器調度
如果有多個CPU,則負載分配成為可能,同時相應的調度問題也變得更為複雜。與單一處理器的CPU調度一樣沒有最好的調度演算法。在多處理器上的CPU調度通常有兩種方法,如下:
非對稱式多處理:讓一個處理器處理所有調度決定、I/O處理以及其他系統活動,其他的處理器只執行使用者代碼。這種方法更簡單,因為只有一個處理器訪問系統資料結構,減輕了資料共用的需要。
對稱式多處理(SMP):每個處理器自我調度,調度通過每個處理器檢查共同就緒隊列並選擇一個進程來執行。現在的作業系統一般都支援這種方式。
由於CPU的調度,因此一個進程通常不會在處理器上一次性執行完,中間可能會讓出CPU,對於對稱式多處理調度方法,則有可能進程從一個處理器遷移到另外一個處理器上執行,而進程相關的資料在原處理器的緩衝中,這樣會導致快取無效判定和重建,其代價很高;因此絕大多數非對稱系統都盡量使一個進程在同一個處理器上運行,這個被稱為處理器親和性。
通過提供多個物理處理器,SMP系統允許同時運行幾個線程。還有一種是提供多個邏輯處理器而不是物理處理器來實現,這種方法稱為對稱多線程(SMT)。也叫超執行緒技術。SMT實際上就是在一個物理處理器上產生多個邏輯處理器,向作業系統呈現一個多邏輯處理器的視圖,同時每個邏輯處理器都有它自己的架構狀態,包括通用的目的和機器狀態寄存器。但是這種技術是需要硬體提供支援,而不是軟體,硬體應該提供每個邏輯處理器的架構狀態的表示和中斷處理方法。