1. 程式人生 > >【面試準備】作業系統知識梳理

【面試準備】作業系統知識梳理

網上看到的資料,和大家分享一下~~~~

作業系統 

1. 程序的有哪幾種狀態,狀態轉換圖,及導致轉換的事件。

2. 程序與執行緒的區別。

3. 程序通訊的幾種方式。

程序間通訊主要包括管道, 系統IPC(包括訊息佇列,訊號量,共享儲存), SOCKET. 管道包括三種:1)普通管道PIPE, 通常有種限制,一是半雙工,只能單向傳輸;二是隻能在父子程序間使用. 2)流管道s_pipe: 去除了第一種限制,可以雙向傳輸. 3)命名管道:name_pipe, 去除了第二種限制,可以在許多並不相關的程序之間進行通訊. 系統IPC的三種方式類同,都是使用了核心裡的識別符號來識別.

# 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。

# 有名管道 (named pipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程序間的通訊。

# 訊號量( semophore ) : 訊號量是一個計數器,可以用來控制多個程序對共享資源的訪問。它常作為一種鎖機制,防止某程序正在訪問共享資源時,其他程序也訪問該資源。因此,主要作為程序間以及同一程序內不同執行緒之間的同步手段。

# 訊息佇列( message queue ) : 訊息佇列是由訊息的連結串列,存放在核心中並由訊息佇列識別符號標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。

# 訊號 ( sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程序某個事件已經發生。

# 共享記憶體( shared memory ) :共享記憶體就是對映一段能被其他程序所訪問的記憶體,這段共享記憶體由一個程序建立,但多個程序都可以訪問。共享記憶體是最快的 IPC 方式,它是針對其他程序間通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號兩,配合使用,來實現程序間的同步和通訊。

# 套接字( socket ) : 套解口也是一種程序間通訊機制,與其他通訊機制不同的是,它可用於不同及其間的程序通訊。

4. 執行緒同步幾種方式。(一定要會寫生產者、消費者問題,完全消化理解)

5. 執行緒的實現方式. (也就是使用者執行緒與核心執行緒的區別)

1、在使用者空間中實現執行緒

(1)特點:核心對執行緒包一無所知。從核心角度考慮,就是按正常的方式管理,即單執行緒程序(存在執行時系統)

(2)優點

使用者級執行緒包可以在不支援執行緒的作業系統上實現

儲存執行緒狀態的過程和呼叫程式都只是本地過程,故啟動它們比程序核心呼叫效率更高

不需要陷阱,不需要上下文切換,也不需要對記憶體快取記憶體進行重新整理,使得執行緒呼叫非常快捷

(3)缺點

執行緒發生I/O或頁面故障引起的阻塞時,如果呼叫阻塞系統呼叫則核心由於不知道有多執行緒的存在,而會阻塞整個程序從而阻塞所有執行緒

一個單獨的程序內部,沒有時鐘中斷,所以不可能用輪轉排程的方式排程執行緒

2、在核心中實現執行緒

(1)特點

當某個執行緒希望建立一個新執行緒或撤銷一個已有執行緒時,它進行一個系統呼叫

(2)優點

所有能夠阻塞執行緒的呼叫都以系統呼叫的形式實現,代價可觀

當一個執行緒阻塞時,核心根據選擇可以執行另一個程序的執行緒,而使用者空間實現的執行緒中,執行時系統始終執行自己程序中的執行緒

說明:由於核心建立執行緒代價大,故有執行緒回收

3、訊號是發給程序而不是執行緒的,當一個訊號到達時,應該由哪一個執行緒處理它?執行緒可以“註冊”它們感興趣的訊號。但如果兩個或更多的執行緒註冊了相同的訊號,會發生什麼呢?

下面是執行緒包實現圖

 

4、混合實現

在這種模型中,每個核心級執行緒有一個可以輪流使用的使用者級執行緒集合

6. 使用者態和核心態的區別。

當一個任務(程序)執行系統呼叫而陷入核心程式碼中執行時,我們就稱程序處於核心執行態(或簡稱為核心態)。此時處理器處於特權級最高的(0級)核心程式碼中 執行。當程序處於核心態時,執行的核心程式碼會使用當前程序的核心棧。每個程序都有自己的核心棧。當程序在執行使用者自己的程式碼時,則稱其處於使用者執行態(用 戶態)。即此時處理器在特權級最低的(3級)使用者程式碼中執行。當正在執行使用者程式而突然被中斷程式中斷時,此時使用者程式也可以象徵性地稱為處於程序的核心 態。因為中斷處理程式將使用當前程序的核心棧。這與處於核心態的程序的狀態有些類似。 核心態與使用者態是作業系統的兩種執行級別,跟 intel cpu沒有必然的聯絡, intel cpu提供Ring0-Ring3三種級別的執行模式,Ring0級別最高,Ring3最低。Linux使用了Ring3級別執行使用者態,Ring0作為 核心態,沒有使用Ring1和Ring2。Ring3狀態不能訪問Ring0的地址空間,包括程式碼和資料。Linux程序的4GB地址空間,3G-4G部 分大家是共享的,是核心態的地址空間,這裡存放在整個核心的程式碼和所有的核心模組,以及核心所維護的資料。使用者執行一個程式,該程式所建立的程序開始是運 行在使用者態的,如果要執行檔案操作,網路資料傳送等操作,必須通過write,send等系統呼叫,這些系統呼叫會呼叫核心中的程式碼來完成操作,這時,必 須切換到Ring0,然後進入3GB-4GB中的核心地址空間去執行這些程式碼完成操作,完成後,切換回Ring3,回到使用者態。這樣,使用者態的程式就不能 隨意操作核心地址空間,具有一定的安全保護作用。 至於說保護模式,是說通過記憶體頁表操作等機制,保證程序間的地址空間不會互相沖突,一個程序的操作不會修改另一個程序的地址空間中的資料。

7. 使用者棧和核心棧的區別。

程序是程式的一次執行過程。用劇本和演出來類比,程式相當於劇本,而程序則相當於劇本的一次演出,舞臺、燈光則相當於程序的執行環境。

程序的堆疊

每個程序都有自己的堆疊,核心在建立一個新的程序時,在建立程序控制塊task_struct的同時,也為程序建立自己堆疊。一個程序 有2個堆疊,使用者堆疊和系統堆疊;使用者堆疊的空間指向使用者地址空間,核心堆疊的空間指向核心地址空間。當程序在使用者態執行時,CPU堆疊指標暫存器指向的 使用者堆疊地址,使用使用者堆疊,當程序執行在核心態時,CPU堆疊指標暫存器指向的是核心棧空間地址,使用的是核心棧;

程序使用者棧和核心棧之間的切換

當程序由於中斷或系統呼叫從使用者態轉換到核心態時,程序所使用的棧也要從使用者棧切換到核心棧。系統呼叫實質就是通過指令產生中斷,稱為軟中斷。程序因為中斷(軟中斷或硬體產生中斷),使得CPU切換到特權工作模式,此時程序陷入核心態,程序進入核心態後,首先把使用者態的堆疊地址儲存在核心堆疊中,然後設定堆疊指標暫存器的地址為核心棧地址,這樣就完成了使用者棧向核心棧的切換。

當程序從核心態切換到使用者態時,最後把儲存在核心棧中的使用者棧地址恢復到CPU棧指標暫存器即可,這樣就完成了核心棧向用戶棧的切換。

這裡要理解一下核心堆疊。前面我們講到,程序從使用者態進入核心態時,需要在核心棧中儲存使用者棧的地址。那麼進入核心態時,從哪裡獲得核心棧的棧指標呢?

要解決這個問題,先要理解從使用者態剛切換到核心態以後,程序的核心棧總是空的。這點很好理解,當程序在使用者空間執行時,使用的是使用者棧;當程序在核心態執行時,核心棧中儲存程序在核心態執行的相關資訊,但是當程序完成了核心態的執行,重新回到使用者態時,此時核心棧中儲存的資訊全部恢復,也就是說,程序在核心態中的程式碼執行完成回到使用者態時,核心棧是空的。

理解了從使用者態剛切換到核心態以後,程序的核心棧總是空的,那剛才這個問題就很好理解了,因為核心棧是空的,那當程序從使用者態切換到核心態後,把核心棧的棧頂地址設定給CPU的棧指標暫存器就可以了。

8. 記憶體池、程序池、執行緒池。(c++程式設計師必須掌握)

記憶體池

記憶體池是一種記憶體分配方式。通常我們習慣直接使用new、malloc等系統呼叫申請分配記憶體,這樣做的缺點在於:由於所申請記憶體塊的大小不定,當頻繁使用時會造成大量的記憶體碎片並進而降低效能。

記憶體池則是在真正使用記憶體之前,先申請分配一定數量的、大小相等(一般情況下)的記憶體塊留作備用。當有新的記憶體需求時,就從記憶體池中分出一部分記憶體塊,若記憶體塊不夠再繼續申請新的記憶體。這樣做的一個顯著優點是,使得記憶體分配效率得到提升。

程序池和執行緒池

程序池和執行緒池相似,所以這裡我們以程序池為例進行介紹。如沒有特殊宣告,下面對程序池的描述也適用於執行緒池。

程序池是由伺服器預先建立的一組子程序,這些子程序的數目在3~10 個之間(當然這只是典型情況)。執行緒池中的執行緒數量應該和 CPU 數量差不多。

程序池中的所有子程序都執行著相同的程式碼,並具有相同的屬性,比如優先順序、PGID 等。

當有新的任務來到時,主程序將通過某種方式選擇程序池中的某一個子程序來為之服務。相比於動態建立子程序,選擇一個已經存在的子程序的代價顯得小得多。至於主程序選擇哪個子程序來為新任務服務,則有兩種方法:

1)主程序使用某種演算法來主動選擇子程序。最簡單、最常用的演算法是隨機演算法和 Round Robin (輪流演算法)。

2)主程序和所有子程序通過一個共享的工作佇列來同步,子程序都睡眠在該工作佇列上。當有新的任務到來時,主程序將任務新增到工作佇列中。這將喚醒 正在等待任務的子程序,不過只有一個子程序將獲得新任務的“接管權”,它可以從工作佇列中取出任務並執行之,而其他子程序將繼續睡眠在工作佇列上。

當選擇好子程序後,主程序還需要使用某種通知機制來告訴目標子程序有新任務需要處理,並傳遞必要的資料。最簡單的方式是,在父程序和子程序之間預先建立好一條管道,然後通過管道來實現所有的程序間通訊。在父執行緒和子執行緒之間傳遞資料就要簡單得多,因為我們可以把這些資料定義為全域性,那麼它們本身就是被所有執行緒共享的。

執行緒池主要用於:

1)需要大量的執行緒來完成任務,且完成任務的時間比較短。 比如WEB伺服器完成網頁請求這樣的任務,使用執行緒池技術是非常合適的。因為單個任務小,而任務數量巨大。但對於長時間的任務,比如一個Telnet連線 請求,執行緒池的優點就不明顯了。因為Telnet會話時間比執行緒的建立時間大多了。

2)對效能要求苛刻的應用,比如要求伺服器迅速響應客戶請求。

3)接受突發性的大量請求,但不至於使伺服器因此產生大量執行緒的應用。

9. 死鎖的概念,導致死鎖的原因.

10.導致死鎖的四個必要條件。

11.  處理死鎖的四個方式。

12. 預防死鎖的方法、避免死鎖的方法 。

13. 程序排程演算法。(週轉時間 =  程式結束時間 -- 開始服務時間、帶權週轉時間=  週轉時間 /  要求服務時間)

一、先來先服務和短作業(程序)優先排程演算法

1.先來先服務排程演算法

先來先服務(FCFS)排程演算法是一種最簡單的排程演算法,該演算法既可用於作業排程,也可用於程序排程。當在作業排程中採用該演算法時,每次排程都是從 後備作業佇列中選擇一個或多個最先進入該佇列的作業,將它們調入記憶體,為它們分配資源、建立程序,然後放入就緒佇列。在程序排程中採用FCFS演算法時,則 每次排程是從就緒佇列中選擇一個最先進入該佇列的程序,為之分配處理機,使之投入執行。該程序一直執行到完成或發生某事件而阻塞後才放棄處理機。

2.短作業(程序)優先排程演算法

短作業(程序)優先排程演算法SJ(P)F,是指對短作業或短程序優先排程的演算法。它們可以分別用於作業排程和程序排程。 短作業優先(SJF)的排程演算法是從後備佇列中選擇一個或若干個估計執行時間最短的作業,將它們調入記憶體執行。而短程序優先(SPF)排程演算法則是從就緒 佇列中選出一個估計執行時間最短的程序,將處理機分配給它,使它立即執行並一直執行到完成,或發生某事件而被阻塞放棄處理機時再重新排程。

二、高優先權優先排程演算法

1.優先權排程演算法的型別

為了照顧緊迫型作業,使之在進入系統後便獲得優先處理,引入了最高優先權優先(FPF)排程演算法。此演算法常被用於批處理系統中,作為作業排程演算法,也作為多種作業系統中的程序排程演算法,還可用於實時系統中。當把該演算法用於作業排程時,系統將從後備佇列中選擇若干個優先權最高的作業裝入記憶體。當用於程序排程時,該演算法是把處理機分配給就緒佇列中優先權最高的程序,這時,又可進一步把該演算法分成如下兩種。

1) 非搶佔式優先權演算法

在這種方式下,系統一旦把處理機分配給就緒佇列中優先權最高的程序後,該程序便一直執行下去,直至完成;或因發生某事件使該程序放棄處理機時,系統方可再將處理機重新分配給另一優先權最高的程序。這種排程演算法主要用於批處理系統中;也可用於某些對實時性要求不嚴的實時系統中。

2) 搶佔式優先權排程演算法

在這種方式下,系統同樣是把處理機分配給優先權最高的程序,使之執行。但在其執行期間,只要又出現了另一個其優先權更高的程序,程序排程程式就立即停止當前程序(原優先權最高的程序)的執行,重新將處理機分配給新到的優先權最高的程序。因此,在採用這種排程演算法時,是每當 系統中出現一個新的就緒程序i 時,就將其優先權Pi與正在執行的程序j 的優先權Pj進行比較。如果Pi≤Pj,原程序Pj便繼續執行;但如果是Pi>Pj,則立即停止Pj的執行,做程序切換,使i 程序投入執行。顯然,這種搶佔式的優先權排程演算法能更好地滿足緊迫作業的要求,故而常用於要求比較嚴格的實時系統中,以及對效能要求較高的批處理和分時系 統中。

2.高響應比優先排程演算法

在批處理系統中,短作業優先演算法是一種比較好的演算法,其主要的不足之處是長作業的執行得不到保證。如果我們能為每個作業引入前面所述的動態優先權,並使作業的優先順序隨著等待時間的增加而以速率a 提高,則長作業在等待一定的時間後,必然有機會分配到處理機。該優先權的變化規律可描述為: 由於等待時間與服務時間之和就是系統對該作業的響應時間,故該優先權又相當於響應比RP。據此,又可表示為: 由上式可以看出:

(1) 如果作業的等待時間相同,則要求服務的時間愈短,其優先權愈高,因而該演算法有利於短作業。

(2) 當要求服務的時間相同時,作業的優先權決定於其等待時間,等待時間愈長,其優先權愈高,因而它實現的是先來先服務。

(3) 對於長作業,作業的優先順序可以隨等待時間的增加而提高,當其等待時間足夠長時,其優先順序便可升到很高,從而也可獲得處理機。簡言之,該演算法既照顧了短作 業,又考慮了作業到達的先後次序,不會使長作業長期得不到服務。因此,該演算法實現了一種較好的折衷。當然,在利用該演算法時,每要進行排程之前,都須先做響 應比的計算,這會增加系統開銷。

三、基於時間片的輪轉排程演算法

1.時間片輪轉法

1) 基本原理

在早期的時間片輪轉法中,系統將所有的就緒程序按先來先服務的原則排成一個佇列,每次排程時,把CPU 分配給隊首程序,並令其執行一個時間片。時間片的大小從幾ms 到幾百ms。當執行的時間片用完時,由一個計時器發出時鐘中斷請求,排程程式便據此訊號來停止該程序的執行,並將它送往就緒佇列的末尾;然後,再把處理機 分配給就緒佇列中新的隊首程序,同時也讓它執行一個時間片。這樣就可以保證就緒佇列中的所有程序在一給定的時間內均能獲得一時間片的處理機執行時間。換言 之,系統能在給定的時間內響應所有使用者的請求。

2.多級反饋佇列排程演算法

前面介紹的各種用作程序排程的演算法都有一定的侷限性。如短程序優先的排程演算法,僅照顧了短程序而忽略了長程序,而且如果並未指明程序的長度,則短程序優先和基於程序長度的搶佔式排程演算法都將無法使用。而多級反饋佇列排程演算法則不必事先知道各種程序所需的執行時間,而且還可以滿足各種型別程序的需要,因而它是目前被公認的一種較好的程序排程演算法。在採用多級反饋佇列排程演算法的系統中,排程演算法的實施過程如下所述。

(1) 應設定多個就緒佇列,併為各個佇列賦予不同的優先順序。第一個佇列的優先順序最高,第二個佇列次之,其餘各佇列的優先權逐個降低。該演算法賦予各個佇列中程序執 行時間片的大小也各不相同,在優先權愈高的佇列中,為每個程序所規定的執行時間片就愈小。例如,第二個佇列的時間片要比第一個佇列的時間片長一倍,……, 第i+1個佇列的時間片要比第i個佇列的時間片長一倍。

(2) 當一個新程序進入記憶體後,首先將它放入第一佇列的末尾,按FCFS原則排隊等待排程。當輪到該程序執行時,如它能在該時間片內完成,便可準備撤離系統;如 果它在一個時間片結束時尚未完成,排程程式便將該程序轉入第二佇列的末尾,再同樣地按FCFS原則等待排程執行;如果它在第二佇列中執行一個時間片後仍未 完成,再依次將它放入第三佇列,……,如此下去,當一個長作業(程序)從第一佇列依次降到第n佇列後,在第n 佇列便採取按時間片輪轉的方式執行。

(3) 僅當第一佇列空閒時,排程程式才排程第二佇列中的程序執行;僅當第1~(i-1)佇列均空時,才會排程第i佇列中的程序執行。如果處理機正在第i佇列中為 某程序服務時,又有新程序進入優先權較高的佇列(第1~(i-1)中的任何一個佇列),則此時新程序將搶佔正在執行程序的處理機,即由排程程式把正在執行 的程序放回到第i佇列的末尾,把處理機分配給新到的高優先權程序。

14. Windows記憶體管理的方式(塊式、頁式、段式、段頁式).

分頁儲存管理基本思想: 使用者程式的地址空間被劃分成若干固定大小的區域,稱為“頁”,相應地,記憶體空間分成若干個物理塊,頁和塊的大小相等。可將使用者程式的任一頁放在記憶體的任一塊中,實現了離散分配。 分段儲存管理基本思想: 將使用者程式地址空間分成若干個大小不等的段,每段可以定義一組相對完整的邏輯資訊。儲存分配時,以段為單位,段與段在記憶體中可以不相鄰接,也實現了離散分配。 段頁式儲存管理基本思想: 分頁系統能有效地提高記憶體的利用率,而分段系統能反映程式的邏輯結構,便於段的共享與保護,將分頁與分段兩種儲存方式結合起來,就形成了段頁式儲存管理方式。 在段頁式儲存管理系統中,作業的地址空間首先被分成若干個邏輯分段,每段都有自己的段號,然後再將每段分成若干個大小相等的頁。對於主存空間也分成大小相等的頁,主存的分配以頁為單位。 段頁式系統中,作業的地址結構包含三部分的內容:段號     頁號       頁內位移量 程式設計師按照分段系統的地址結構將地址分為段號與段內位移量,地址變換機構將段內位移量分解為頁號和頁內位移量。 為實現段頁式儲存管理,系統應為每個程序設定一個段表,包括每段的段號,該段的頁表始址和頁表長度。每個段有自己的頁表,記錄段中的每一頁的頁號和存放在主存中的物理塊號。

15. 記憶體連續分配方式採用的幾種演算法及各自優劣。

單一連續分配

記憶體在此方式下分為系統區和使用者區,系統區僅提供給作業系統使用,通常在低地址部分;使用者區是為使用者提供的、除系統區之外的記憶體空間。這種方式無需進行記憶體保護。 這種方式的優點是簡單、無外部碎片,可以釆用覆蓋技術,不需要額外的技術支援。缺點是隻能用於單使用者、單任務的作業系統中,有內部碎片,儲存器的利用率極低。

固定分割槽分配

固定分割槽分配是最簡單的一種多道程式儲存管理方式,它將使用者記憶體空間劃分為若干個固定大小的區域,每個分割槽只裝入一道作業。當有空閒分割槽時,便可以再從外存的後備作業佇列中,選擇適當大小的作業裝入該分割槽,如此迴圈。

圖3-4  固定分割槽分配的兩種方法

固定分割槽分配在劃分分割槽時,有兩種不同的方法,如圖3-4所示。

· 分割槽大小相等:用於利用一臺計算機去控制多個相同物件的場合,缺乏靈活性。

· 分割槽大小不等:劃分為含有多個較小的分割槽、適量的中等分割槽及少量的大分割槽。

為便於記憶體分配,通常將分割槽按大小排隊,併為之建立一張分割槽說明表,其中各表項包括每個分割槽的起始地址、大小及狀態(是否已分配),如圖3-5(a)所 示。當有使用者程式要裝入時,便檢索該表,以找到合適的分割槽給予分配並將其狀態置為”已分配”;未找到合適分割槽則拒絕為該使用者程式分配記憶體。儲存空間的分配 情況如圖3-5(b)所示。 這種分割槽方式存在兩個問題:一是程式可能太大而放不進任何一個分割槽中,這時使用者不得不使用覆蓋技術來使用記憶體空間;二是主存利用率低,當程式小於固定分割槽大小時,也佔用了一個完整的記憶體分割槽空間,這樣分割槽內部有空間浪費,這種現象稱為內部碎片。 固定分割槽是可用於多道程式設計最簡單的儲存分配,無外部碎片,但不能實現多程序共享一個主存區,所以儲存空間利用率低。固定分割槽分配很少用於現在通用的作業系統中,但在某些用於控制多個相同物件的控制系統中仍發揮著一定的作用。

圖3-5  固定分割槽說明表和記憶體分配情況

動態分割槽分配

動態分割槽分配又稱為可變分割槽分配,是一種動態劃分記憶體的分割槽方法。這種分割槽方法不預先將記憶體劃分,而是在程序裝入記憶體時,根據程序的大小動態地建立分割槽,並使分割槽的大小正好適合程序的需要。因此係統中分割槽的大小和數目是可變的。

圖3-6動態分割槽

如圖3-6所示,系統有64MB記憶體空間,其中低8MB固定分配給作業系統,其餘為使用者可用記憶體。開始時裝入前三個程序,在它們分別分配到所需空間後,內 存只剩下4MB,程序4無法裝入。在某個時刻,記憶體中沒有一個就緒程序,CPU出現空閒,作業系統就換出程序2,換入程序4。由於程序4比程序2小,這樣 在主存中就產生了一個6MB的記憶體塊。之後CPU又出現空閒,而主存無法容納程序2,作業系統就換出程序1,換入程序2。 動態分割槽在開始分配時是很好的,但是之後會導致記憶體中出現許多小的記憶體塊。隨著時間的推移,記憶體中會產生越來越多的碎片(圖3-6中最後的4MB和中間的 6MB,且隨著程序的換入/換出,很可能會出現更多更小的記憶體塊),記憶體的利用率隨之下降。這些小的記憶體塊稱為外部碎片,指在所有分割槽外的儲存空間會變成 越來越多的碎片,這與固定分割槽中的內部碎片正好相對。克服外部碎片可以通過緊湊(Compaction)技術來解決,就是作業系統不時地對程序進行移動和 整理。但是這需要動態重定位暫存器的支援,且相對費時。緊湊的過程實際上類似於Windows系統中的磁碟整理程式,只不過後者是對外存空間的緊湊。 在程序裝入或換入主存時,如果記憶體中有多個足夠大的空閒塊,作業系統必須確定分配哪個記憶體塊給程序使用,這就是動態分割槽的分配策略,考慮以下幾種演算法:

· 首次適應(First  Fit)演算法:空閒分割槽以地址遞增的次序連結。分配記憶體時順序查詢,找到大小能滿足要求的第一個空閒分割槽。

· 最佳適應(Best  Fit)演算法:空閒分割槽按容量遞增形成分割槽鏈,找到第一個能滿足要求的空閒分割槽。

· 最壞適應(Worst  Fit)演算法:又稱最大適應(Largest Fit)演算法,空閒分割槽以容量遞減的次序連結。找到第一個能滿足要求的空閒分割槽,也就是挑選出最大的分割槽。

· 鄰近適應(Next  Fit)演算法:又稱迴圈首次適應演算法,由首次適應演算法演變而成。不同之處是分配記憶體時從上次查詢結束的位置開始繼續查詢。

在這幾種方法中,首次適應演算法不僅是最簡單的,而且通常也是最好和最快的。在UNIX 系統的最初版本中,就是使用首次適應演算法為程序分配記憶體空間,其中使用陣列的資料結構 (而非連結串列)來實現。不過,首次適應演算法會使得記憶體的低地址部分出現很多小的空閒分割槽,而每次分配查詢時,都要經過這些分割槽,因此也增加了查詢的開銷。 鄰近適應演算法試圖解決這個問題,但實際上,它常常會導致在記憶體的末尾分配空間(因為在一遍掃描中,記憶體前面部分使用後再釋放時,不會參與分配),分裂成小碎片。它通常比首次適應演算法的結果要差。 最佳適應演算法雖然稱為“最佳”,但是效能通常很差,因為每次最佳的分配會留下很小的難以利用的記憶體塊,它會產生最多的外部碎片。 最壞適應演算法與最佳適應演算法相反,選擇最大的可用塊,這看起來最不容易產生碎片,但是卻把最大的連續記憶體劃分開,會很快導致沒有可用的大的記憶體塊,因此效能也非常差。

16. 動態連結及靜態連結.

17. 基本分頁、請求分頁儲存管理方式。

1) 一次性。要求將作業全部裝入記憶體後方能執行。許多作業在每次執行時,並非其全部程式和資料都要用到。如果一次性地裝入其全部程式,造成記憶體空間的浪費。 2) 駐留性。作業裝入記憶體後,便一直駐留在記憶體中,直至作業執行結束。儘管執行中的程序會因I/O而長期等待,或有的程式模組在執行過一次後就不再需要(執行)了,但它們都仍將繼續佔用寶貴的記憶體資源。 請求分頁儲存管理是實現虛擬儲存器的一種常用方式,它是在基本分頁儲存管理的基礎上實現的。其基本思想是:在程序開始執行之前,僅裝入當前要執行的部分頁面即可執行;在執行過程中,可使用請求調入中斷動態裝入要訪問但又不在記憶體的頁面;當記憶體空間已滿,而又需要裝入新的頁面時,者根據置換功能適當調出某個頁面,以便騰出空間而裝入新的頁面。為實現請求分頁,需要一定的硬體支援,包括:頁表機制、缺頁中斷機構、地址變換機構。

18. 基本分段、請求分段儲存管理方式。

19.  分段分頁方式的比較各自優缺點。

連續,設計簡單,直接定址,效率高。缺點:記憶體利用效率最低。 分頁,設計最複雜,容易產生碎片,無論資料有多少,都只能按照頁面大小分配,造成浪費。 分段,可以有效利用記憶體,缺點,無法利用碎片,必須搬移記憶體,造成效能損失。

20. 幾種頁面置換演算法,會算所需換頁數。(LRU用程式如何實現?)

1 先入先出法(FIFO)

最簡單的頁面置換演算法是先入先出(FIFO)法。這種演算法的實質是,總是選擇在主存中停留時間最長(即最老)的一頁置換,即先進入記憶體的頁,先退出記憶體。理由是:最早調入記憶體的頁,其不再被使用的可能性比剛調入記憶體的可能性大。建立一個FIFO佇列,收容所有在記憶體中的頁。被置換頁面總是在佇列頭上進行。當一個頁面被放入記憶體時,就把它插在隊尾上。 這種演算法只是在按線性順序訪問地址空間時才是理想的,否則效率不高。因為那些常被訪問的頁,往往在主存中也停留得最久,結果它們因變“老”而不得不被置換出去。 FIFO的另一個缺點是,它有一種異常現象,即在增加儲存塊的情況下,反而使缺頁中斷率增加了。當然,導致這種異常現象的頁面走向實際上是很少見的。

2 最優置換演算法(OPT)

最優置換(Optimal Replacement)是在理論上提出的一種演算法。其實質是:當調入新的一頁而必須預先置換某個老頁時,所選擇的老頁應是將來不再被使用,或者是在最遠的將來才被訪問。採用這種頁面置換演算法,保證有最少的缺頁率。 但是最優頁面置換演算法的實現是困難的,因為它需要人們預先就知道一個程序整個執行過程中頁面走向的全部情況。不過,這個演算法可用來衡量(如通過模擬實驗分析或理論分析)其他演算法的優劣。

3 最久未使用演算法(LRU)

FIFO演算法和OPT演算法之間的主要差別是,FIFO演算法利用頁面進入記憶體後的時間長短作為置換依據,而OPT演算法的依據是將來使用頁面的時間。如果以最近的過去作為不久將來的近似,那麼就可以把過去最長一段時間裡不曾被使用的頁面置換掉。它的實質是,當需要置換一頁時,選擇在最近一段時間裡最久沒有使用過的頁面予以置換。這種演算法就稱為最久未使用演算法(Least Recently Used,LRU)。 LRU演算法是與每個頁面最後使用的時間有關的。當必須置換一個頁面時,LRU演算法選擇過去一段時間裡最久未被使用的頁面。 LRU演算法是經常採用的頁面置換演算法,並被認為是相當好的,但是存在如何實現它的問題。LRU演算法需要實際硬體的支援。其問題是怎麼確定最後使用時間的順序,對此有兩種可行的辦法: (1) 計數器。最簡單的情況是使每個頁表項對應一個使用時間欄位,並給CPU增加一個邏輯時鐘或計數器。每次儲存訪問,該時鐘都加1。每當訪問一個頁面時,時鐘 暫存器的內容就被複制到相應頁表項的使用時間欄位中。這樣我們就可以始終保留著每個頁面最後訪問的“時間”。在置換頁面時,選擇該時間值最小的頁面。這樣 做,不僅要查頁表,而且當頁表改變時(因CPU排程)要維護這個頁表中的時間,還要考慮到時鐘值溢位的問題。 (2)棧。用一個棧保留頁號。每當訪 問一個頁面時,就把它從棧中取出放在棧頂上。這樣一來,棧頂總是放有目前使用最多的頁,而棧底放著目前最少使用的頁。由於要從棧的中間移走一項,所以要用 具有頭尾指標的雙向鏈連起來。在最壞的情況下,移走一頁並把它放在棧頂上需要改動6個指標。每次修改都要有開銷,但需要置換哪個頁面卻可直接得到,用不著 查詢,因為尾指標指向棧底,其中有被置換頁。 因實現LRU演算法必須有大量硬體支援,還需要一定的軟體開銷。所以實際實現的都是一種簡單有效的LRU近似演算法。 一種LRU近似演算法是最近未使用演算法(Not Recently Used,NUR)。它在儲存分塊表的每一表項中增加一個引用位,作業系統定期地將它們置為0。當某一頁被訪問時,由硬體將該位置1。過一段時間後,通過 檢查這些位可以確定哪些頁使用過,哪些頁自上次置0後還未使用過。就可把該位是0的頁淘汰出去,因為在最近一段時間裡它未被訪問過。

4 第二次機會演算法(SCR)

第二次機會演算法的基本思想是與FIFO相同的,但是有所改進,避免把經常使用的頁面置換出去。 當選擇置換頁面時,檢查它的訪問位。如果是0,就淘汰這頁;如果訪問位是1,就給它第二次機會,並選擇下一個FIFO頁面。當一個頁面得到第二次機會時, 它的訪問位就清為0,它的到達時間就置為當前時間。如果該頁在此期間被訪問過,則訪問位置1。這樣給了第二次機會的頁面將不被淘汰,直至所有其他頁面被淘 汰過(或者也給了第二次機會)。因此,如果一個頁面經常使用,它的訪問位總保持為1,它就從來不會被淘汰出去。 第二次機會演算法可視為一個環形佇列。用一個指標指示哪一頁是下面要淘汰的。當需要一個儲存塊時,指標就前進,直至找到訪問位是0的頁。隨著指標的前進,把訪問位就清為0。在最壞的情況 下,所有的訪問位都是1,指標要通過整個佇列一週,每個頁都給第二次機會。這時就退化成FIFO演算法了。

頁面置換演算法還有很多變種,如考慮到被置換頁是否修改過、按FIFO演算法選中的頁正在使用等情況,都需要硬體、軟體協同實現。

21. 虛擬記憶體的定義及實現方式。

虛擬記憶體是指為了擴充主存空間而在外存上開闢的一塊儲存空間.虛擬記憶體用來儲存實際記憶體中暫時不用的程式或資料,使實際記憶體有更多的空閒空間來存放將要執 行的程式或訪問的資料,當需要執行的程式或訪問的資料不在主存時,就從虛擬記憶體將其調入到主存,以便處理器執行或訪問,這樣就擴大了記憶體空間,作業系統對 實際記憶體和虛擬記憶體統一編址和統一管理,這就是虛擬記憶體技術. 大多數的多工作業系統都採用分頁儲存方式,使用虛擬記憶體技術.UNIX作業系統採 用頁面儲存方式,Windows NT採用請求分頁的虛擬儲存方式,Linux系統採用按需調頁的模式.在AIX系統中,也使用分頁的儲存方式管理儲存器,並將虛擬記憶體稱為頁面空間 (Paging Space),所有對實際實體記憶體和虛擬記憶體的訪問都是由虛擬記憶體管理器(VMM)完成的.

22. 作業系統的四個特性。

23. DMA。

DMA是指外部裝置不通過CPU而直接與系統記憶體交換資料的介面技術。

要把外設的資料讀入記憶體或把記憶體的資料傳送到外設,一般都要通過CPU控制完成,如CPU程式查詢或中斷方式。利用中斷進行資料傳送,可以大大提高CPU的利用率

    但是採用中斷傳送有它的缺點,對於一個高速I/O裝置,以及批量交換資料的情況,只能採用DMA方式,才能解決效率和速度問題。DMA在外設與記憶體間直接進行資料交換,而不通過CPU,這樣資料傳送的速度就取決於儲存器和外設的工作速度。

通常系統的匯流排是由CPU管理的。在DMA方式時,就希望CPU把這些匯流排讓出來,即CPU連到這些總線上的線處於第三態--高阻狀態,而由DMA控制器接管,控制傳送的位元組數,判斷DMA是否結束,以及發出DMA結束訊號。DMA控制器必須有以下功能:

1. 能向CPU發出系統保持(HOLD)訊號,提出匯流排接管請求;

2. 當CPU發出允許接管訊號後,負責對匯流排的控制,進入DMA方式;

3. 能對儲存器定址及能修改地址指標,實現對記憶體的讀寫操作;

4. 能決定本次DMA傳送的位元組數,判斷DMA傳送是否結束

5. 發出DMA結束訊號,使CPU恢復正常工作狀態。

24. Spooling。

已經被廣泛用於多使用者系統和計算機網路中,它實際上就是利用SPOOLING技術將獨佔的印表機改造為一臺供做個使用者共享的裝置,只要有足夠的外存空間和多道程式作業系統的支援即可。

1、當用戶程序請求列印輸出時,SPOOLING系統立即同意為該程序執行列印輸出,但並不是真正地把印表機分配給該使用者程序,而只是為該程序做兩項工 作: 一項是由輸出程序SPO在輸出井中為之申請一個空閒的儲存空間,並將要列印的資料傳送其中存放;另一項工作就是由輸出程序SPO再為使用者程序申請一張空白 的使用者請求打印表,並將使用者的列印請求填入其中,然後將該表掛到印表機的請求佇列上。這時,如果還有另一個程序請求印表機時,則系統仍同意為該程序執行打 印輸出,當然,系統所做的工作仍是以上兩項內容。

2、在印表機執行實際列印時,如果印表機空閒,輸出程序SPO將從請求列印佇列的隊首取出一張打印表,根據打印表中的要求將要列印的資料從輸出井傳送到內 存輸出緩衝區,再傳送到印表機列印。列印完後,輸出程序SPO將再檢查請求列印佇列中是否還有待列印的請求表,若有則再取出一張請求打印表,將新的但因要 求繼續列印。如此反覆,直到請求列印佇列空為止,輸出程序才將自己阻塞起來,並在下次再有列印請求時被喚醒。

25. 外存分配的幾種方式,及各種優劣。

    外存,指的是除了cpu快取和記憶體以外的儲存器,硬碟、光碟、U盤都可以被稱為外存。所有的資料,也都存在這裡面,故他的分配方式變得極其重要,這直接影響到了計算機的執行速度。

    外存分配方式主要有這幾種:連續分配,鏈式分配,索引分配。

一.  連續分配

    原理:建立檔案時,分配一組連續的塊;FAT(文件分配表)中每個檔案只要一項,說明起始塊和檔案長度。對於順序檔案有利。

    優點:1.簡便。適用於一次性寫入操作。2.支援順序存取和隨機存取,順序存取速度快。3.所需的磁碟尋道次數和尋道時間最少。(因為空間的連續性,當訪問下一個磁碟塊時,一般無需移動磁頭,當需要移動磁頭時,只需要移動一個磁軌。)

    缺點:1.檔案不能動態增長。(可能檔案末尾處的空塊已經分配給了別的檔案。)2.不利於檔案的插入和刪除。3.外部碎片問題。(反覆增刪檔案後,很難找到空間大小足夠的連續塊,需要進行緊縮。)4.在建立檔案時需生命檔案大小。    

二.  鏈式分配

    原理:一個檔案的資訊存放在若干個不連續的物理塊中,各塊之間通過指標連線,前一個物理塊指向下一個物理塊。fat中每個檔案同樣只需要一項,包括檔名、起始塊號和最後塊號。任何一個自由塊都可以加入到鏈中。

    優點:1.提高磁碟的空間利用率,不存在外部碎片問題。2.有利於檔案的插入和刪除。3.有利於檔案的動態擴充。

    缺點:1.存取速度慢,一般只適用於資訊的順序存取,不適於隨機存取。2.查詢某一塊必須從頭到尾沿著指標進行。3.可靠性問題,如指標出錯。4.更多的尋道次數和尋道時間。5.連結指標佔一定的空間,將多個塊組成簇,按簇進行分配而不是按塊進行分配。(增加了磁碟碎片)

    使用FAT檔案分配表法,連結分配的變種,如MS-DOS 和 OS/2.

三.  索引分配

    原理:每個檔案在FAT中有一個一級索引,索引包含分配給檔案的每個分割槽的入口。檔案的索引儲存在單獨的一個塊中,FAT中該檔案的入口指向這一塊。

    優點:1.保持了連結結構的優點,又解決了其缺點:按快分配可以消除外部碎片。按大小可改變的分割槽分配可以提高區域性性。索引分配支援順序訪問檔案和直接訪問檔案,是普遍採用的一種方式。2.滿足了檔案動態增長,插入刪除的要求。(只要有空閒塊)3.能充分利用外存空間。

    缺點:1.較多的尋道次數和尋道空間。2.索引表本身帶來了系統開銷,如:內外存空間、存取時間。    

四.  連續分配和索引分配相結合

    原理:對於小檔案(3、4塊),採用連續分配;當檔案大時,自動切換到索引分配。

    檔案的直接訪問:使用連續分配方式。

    檔案的順序訪問:採用連結分配。

    對於這些系統,所使用的訪問型別,必須在檔案建立時加以說明。

五.  多重索引

    原理:首先,多重索引也是索引分配的一種,只不過它是將一個大檔案的所有索引表(二級索引)的地址放在另一個索引表(一級索引)中。ps:跟資料庫第四正規化非常像。

    大檔案:設一個盤塊大小為1kb,長度100kb的檔案就需要100個盤塊,索引表至少需要100項;若檔案大小為1000kb,則索引表項就要有1000項。設盤塊號用4個位元組表示,則該索引表至少佔用4000bye(約4k)。    當檔案很大時,存在的問題:1.需要很多磁碟塊。2.索引表很大。3.不能將整個索引表放在記憶體。

    解決途徑:採用多重索引表結構。

推薦書籍:《深入理解現代作業系統》