進程、線程概念
進程:一個進程就是一個正在執行的程序的實例。
進程轉換:
進程3個狀態:運行態,阻塞態,就緒態。
1.進程為等待輸入而阻塞。
2.調度程序選擇另一個進程。
3.調度程序選擇這個進程。
4.出現有效輸入。
線程:輕量級進程。
作業調度:按照某種原則,從后備作業隊列中選取作業進入內存,並為作業做好運行前的准備工作以及作業完成后的善后處理工作。
主要調度算法:
First Come First Serve (FCFS)先來先服務:按到達時間先后排序。
Shorted Job First (nonpreemptive & preemptive ) 最短作業優先:按作業的運行時間排序,由短到長。
Round robin 輪轉調度:每個進程執行一個時間片后移到隊列末尾,把CPU交給下一個進程。
Priority Scheduling (nonpreemptive & preemptive ) 優先級調度:執行當前實時優先級最高的進程。動態優先級是在創建進程時賦予該進程一個初始優先級,然后其優先級隨着進程的執行情況的變化而改變。
Multiple Queues 多級隊列:
1.進程在進入待調度的隊列等待時,首先進入優先級最高的Q1等待。
2.首先調度優先級高的隊列中的進程。若高優先級中隊列中已沒有調度的進程,則調度次優先級隊列中的進程。
3.對於同一個隊列中的各個進程,按照時間片輪轉法調度。
4.在低優先級的隊列中的進程在運行時,又有新到達的作業,那么在運行完這個時間片后,CPU馬上分配給新到達的作業(搶占式)。
多級隊列算法運作過程示例:

用戶空間建立的線程包和內核建立的線程包區別圖
臨界區:每個進程中訪問臨界資源的那段代碼稱為臨界區(Critical Section)(臨界資源是一次僅允許一個進程使用的共享資源)。每次只准許一個進程進入臨界區,進入后不允許其他進程進入。不論是硬件臨界資源,還是軟件臨界資源,多個進程必須互斥地對它進行訪問。
信號量:在多線程環境下使用的一種設施,是可以用來保證兩個或多個關鍵代碼段不被並發調用。在進入一個關鍵代碼段之前,線程必須獲取一個信號量;一旦該關鍵代碼段完成了,那么該線程必須釋放信號量。其它想進入該關鍵代碼段的線程必須等待直到第一個線程釋放信號量。
信號量有兩種操作:down,up,也就是所謂的P,V操作
down:如果信號量大於0,則繼續,等於0則進程將睡眠,將信號量減1。
up:將信號量加1,如果信號量大於0,則繼續,若小於或等於0,則喚醒一阻塞在該信號量上的進程。
例如:Semaphore的初值為n, m個進程使用該semaphore訪問關鍵區,那么semaphore值的變化范圍是多少?
每個進程進入關鍵區時都會使Semaphore減1,離開時又使Semaphore加1,所以范圍是n-m到n。
信號量可以用來解決一些進程同步的問題,例如:
用P、V操作說明互斥量,定出司機與售票員之間的同步算法,司機與售票員活動如下圖所示。
在汽車行駛過程中,司機活動與售票員活動之間的同步關系為:售票員關車門后向司機發開車信號,司機接到開車信號后啟動車輛,在汽車正常行駛過程中售票員售票,到站時司機停車,售票員在車停后開車門讓乘客下車。因此司機啟動車輛的動作必須與售票員關車門的動作取得同步;售票員開車門的動作也必須與司機停車取得同步。
所以在本題中,應設置兩個信號量s1、s2,s1表示是否允許司機啟動汽車,其初值為0;s2表示是否允許售票員開車門,其初值為0。
所以解答為:(可以將P操作看成是wait--等待信號,V操作看成是signal--發出信號)
Semaphore s1,s2=0;
Driver() Saler()
{ {
while(true) while(true)
{ {
p(s1); 關車門;
啟動車輛; v(s1);
正常行車; 售票;
到站停車; p(s2);
v(s2); 開車門;
} 上下乘客;
} }
}
幾個利用信號量和線程解決的IPC(進程間通信)經典問題:
1.生產者與消費者問題
在同一個進程地址空間內執行的兩個線程生產者線程生產物品,然后將物品放置在一個空緩沖區中供消費者線程消費。消費者線程從緩沖區中獲得物品,然后釋放緩沖區。當生產者線程生產物品時,如果沒有空緩沖區可用,那么生產者線程必須等待消費者線程釋放出一個空緩沖區。當消費者線程消費物品時,如果沒有滿的緩沖區,那么消費者線程將被阻塞,直到新的物品被生產出來。
C解決此問題的源碼:
1 #define N 100 //緩沖區的槽數目 2 typedef int semaphore; 3 semaphore mutex = 1 ; //臨界區(緩沖區)信號量,以互斥各線程的進入 4 semaphore empty = N; //緩沖區的空槽數目 5 semaphore full = 0; //緩沖區的滿槽數目 6 void producer(void) 7 { 8 int item; 9 while (TRUE) { 10 item = produce_item( ); 11 down( &empty); //空槽減1 12 down( &mutex); //進入臨界區 13 inserUtem(item); //加入數據 14 up( &mutex); //離開臨界區 15 up( &full); //滿槽加1 16 } 17 } 18 void consumer(void) 19 { 20 int item; 21 while (TRUE) { 22 down( &full); 23 down( &mutex); 24 item = remove_ item( ); 25 up( &mutex); 26 up( &empty); 27 consume_item(item); //消費一個數據項 28 } 29 }
2.哲學家就餐問題
假設有五位哲學家圍坐在一張圓形餐桌旁,做以下兩件事情之一:吃飯,或者思考。吃東西的時候,他們就停止思考,思考的時候也停止吃東西。餐桌中間有一大碗意大利面,每兩個哲學家之間有一只餐叉。因為用一只餐叉很難吃到意大利面,所以假設哲學家必須用兩只餐叉吃東西。他們只能使用自己左右手邊的那兩只餐叉。哲學家就餐問題有時也用米飯和筷子而不是意大利面和餐叉來描述,因為很明顯,吃米飯必須用兩根筷子。
C解決此問題源碼:
PS:philosopher函數未完整,應該修改為下圖:
值得注意的是,philosopher函數會有不同的5個進程來調,參數為 0 到 N-1 。
3.讀者寫者的問題
有一個被許多進程共享的數據區,這個數據區可以是一個文件,或者主存的一塊空間,甚至可以是一組處理器寄存器。有一些只讀取這個數據區的進程(reader)和一些只往數據區中寫數據的進程(writer)。以下假設共享數據區是文件。這些讀者和寫者對數據區的操作必須滿足以下條件:讀—讀允許;讀—寫互斥;寫—寫互斥。這些條件具體來說就是:
(1)任意多的讀進程可以同時讀這個文件;
(2)一次只允許一個寫進程往文件中寫;
(3)如果一個寫進程正在往文件中寫,禁止任何讀進程或寫進程訪問文件;
(4)寫進程執行寫操作前,應讓已有的寫者或讀者全部退出。這說明當有讀者在讀文件時不允許寫者寫文件。
C語言解決此問題源碼:寫者優先算法
死鎖
資源死鎖的4個條件:
現在有5個進程A、B、C、D、E,有4種類型的資源R1、R2、R3、R4。在T0時刻系統狀態如下。R1、R2、R3、R4的剩余資源數依次為3、3、0、3。
回答下面問題:
(1)T0時刻是否為安全狀態?
(2)若這時D提出申請(1,2,0,3),是否能實施資源分配?
虛地址到實地址的翻譯過程
幾種主要的頁面置換算法:
FIFO(First In First Out)先進先出:按照先進先出順序淘汰頁面。(ps:頁面替換時,出現重復頁面,此頁面的順序按照之前的頁面順序算)
LRU( Least Recently Used ) 最近最少使用:將前一段時間內沒使用的頁面置換。
OPT( Optimal )最佳頁面置換算法:




磁盤調度算法
FCFS (First Come First Served) 先來先服務:和進程調度一樣。
最短尋道優先算法(Shortest Seek First):以磁頭位置尋找下一個距離最近的磁道。
SCAN(掃描算法 又稱 電梯算法):第一個磁道選擇離磁頭最近的磁道,然后按照磁頭移動方向依次選擇最近磁道,當此方向上磁道都選擇完畢時,反向選擇最近磁道。
例如:
Inode


文件A和文件B的inode號碼雖然不一樣,但是文件A的內容是文件B的路徑。讀取文件A時,系統會自動將訪問者導向文件B。因此,無論打開哪一個文件,最終讀取的都是文件B。這時,文件A就稱為文件B的"軟鏈接"(soft link)或者"符號鏈接"(symbolic link)。
這意味着,文件A依賴於文件B而存在,如果刪除了文件B,打開文件A就會報錯:"No such file or directory"。這是軟鏈接與硬鏈接最大的不同:文件A指向文件B的文件名,而不是文件B的inode號碼,文件B的inode"鏈接數"不會因此發生變化。
一個分區分成同等大小的簇,也就是連續空間的小塊。簇的大小隨着FAT文件系統的類型以及分區大小而不同,典型的簇大小介於2KB到32KB之間。每個文件根據它的大小可能占有一個或者多個簇;這樣,一個文件就由這些這些(稱為單鏈表)簇鏈所表示。然而,這些鏈並不一定一個接着一個在磁盤上存儲,它們經常是在整個數據區域零散的儲存。
文件分配表(FAT)是映射到分區每個簇的條目列表。每個條目記錄下面五種信息中的一種:
1.鏈中下一個簇的地址
2.一個特殊的文件結束符(EOF)
3.符號指示鏈的結束
4.一個特殊的符號標示壞簇
5.一個特殊的符號標示保留簇 ( 0來表示空閑簇 )
Memory mapped I/O : 就是把磁盤上的file映射到內存上,當我們從內存上fetch byte時,對應的file就被讀取。同樣的,當我們在內存上存儲字節的時候,對應的file就被寫入。這就讓我們不需通過read和write系統調用而去操作I/O。

