【轉載】操作系統常見面試題

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

(1)進程的五狀態模型:

運行態:該進程正在執行。

就緒態:進程已經做好了準備,只要有機會就開始執行。

阻塞態(等待態):進程在某些事情發生前不能執行,等待阻塞進程的事件完成。

新建態:剛剛創建的進程,操作系統還沒有把它加入到可執行進程組中,通常是進程控制塊已經創建但是還沒有加載到內存中的進程。

退出態:操作系統從可執行進程組中釋放出的進程,或由於自身或某種原因停止運行。

 

 

 

(2)上圖顯示了導致進程狀態轉換的事件類型,可能的轉換如下:

空->新建:創建執行一個程序的新進程,可能的事件有:新的批處理作業、交互登錄(終端用戶登錄到系統)、操作系統因爲提供一項服務而創建、由現有的進程派生等。

新建->就緒:操作系統準備好再接納一個進程時,把一個進程從新建態轉換爲就緒態。

就緒->運行:需要選擇一個新進程運行時,操作系統的調度器或分配器根據某種調度算法選擇一個處於就緒態的進程。

運行->退出:導致進程終止的原因有:正常完成、超過時限、系統無法滿足進程需要的內存空間、進程試圖訪問不允許訪問的內存單元(越界)、算術錯誤(如除以0或存儲大於硬件可以接納的數字)、父進程終止(操作系統可能會自動終止該進程所有的後代進程)、父進程請求終止後代進程等。

運行->就緒:最常見的原因是,正在運行的進程到達了“允許不中斷執行”的最大時間段,該把處理器的資源釋放給其他在就緒態的進程使用了;還有一中原因可能是由於具有更改優先級的就緒態進程搶佔了該進程的資源,使其被中斷轉換到就緒態。

運行->阻塞:如果進程請求它必須等待的某些事件,例如一個無法立即得到的資源(如I/O操作),只有在獲得等待的資源後才能繼續進程的執行,則進入等待態(阻塞態)。

阻塞->就緒:當等待的事件發生時,處於阻塞態的進程轉換到就緒態。

就緒->退出:在上圖中沒有標出這種轉換,在某些進程中,父進程可以在任何時刻終止一個子進程,如果一個父進程終止,所有相關的子進程都被終止。

阻塞->退出:跟上一項原因類似。 

 

2.     進程與線程的區別。

在多線程環境中,一個進程被定義成資源分配的單位和一個被保護的單位,與進程相關聯的有

(1)存放進程映像(程序、數據、棧和進程控制塊中定義的屬性的集合)的虛擬地址空間

(2)受保護的對處理器、其他進程(用於進程間通信)、文件和IO資源(設備和通道)的訪問

 

在一個進程中,可能有一個或多個線程,每個線程有

線程執行狀態(運行、就緒等)

² 在未運行時保存的線程上下文

² 一個執行棧

² 用於每個線程局部變量的靜態存儲空間

² 與進程內的其他線程共享的對進程的內存和資源的訪問

在多線程進程中,每個線程都有一個獨立的棧,還有獨立的線程控制塊用於包含寄存器值、優先級和其他與線程相關的狀態信息

在大多數操作系統中,獨立進程間的通信需要內核的介入,以提供保護和通信所需要的機制。但是,由於在同一個進程中的線程共享內存和文件,他們無需調用內核就可以相互通信

 

3.進程通信的幾種方式。

進程間通信主要包括管道, 系統IPC(包括消息隊列,信號量,共享存儲), SOCKET

  管道包括三種:1)普通管道PIPE, 通常有種限制,一是半雙工,只能單向傳輸;二是只能在父子進程間使用. 2)流管道s_pipe: 去除了第一種限制,可以雙向傳輸. 3)命名管道:name_pipe,去除了第二種限制,可以在許多並不相關的進程之間進行通訊.

系統IPC的三種方式類同,都是使用了內核裏的標識符來識別. 

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

有名管道 (namedpipe) : 有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。

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

消息隊列( messagequeue ) : 消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。

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

共享內存( sharedmemory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。

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

 

 

 

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

進程中線程同步的四種常用方式:

(1)臨界區(CriticalSection)

當多個線程訪問一個獨佔性共享資源時,可以使用臨界區對象。擁有臨界區的線程可以訪問被保護起來的資源或代碼段,其他線程若想訪問,則被掛起,直到擁有臨界區的線程放棄臨界區爲止。具體應用方式:

(1、 定義臨界區對象 

(2、 在訪問共享資源(代碼或變量)之前,先獲得臨界區對象

(3、 訪問共享資源後,則放棄臨界區對象

 

(2)事件(Event)

事件機制,則允許一個線程在處理完一個任務後,主動喚醒另外一個線程執行任務。比如在某些網絡應用程序中,一個線程如A負責偵聽通信端口,另外一個線程B負責更新用戶數據,利用事件機制,則線程A可以通知線程B何時更新用戶數據。

 

(3)互斥量(Mutex)

互斥對象和臨界區對象非常相似,只是其允許在進程間使用,而臨界區只限制與同一進程的各個線程之間使用,但是更節省資源,更有效率。

 

(4)信號量(Semphore)

 當需要一個計數器來限制可以使用某共享資源的線程數目時,可以使用“信號量”對象。Semaphore類對象保存了對當前訪問某一個指定資源的線程的計數值,該計數值是當前還可以使用該資源的線程數目。如果這個計數達到了零,則所有對這個Semaphore類對象所控制的資源的訪問嘗試都被放入到一個隊列中等待,直到超時或計數值不爲零爲止。

 

生產者-消費者模型:

要理解生產消費者問題,首先應弄清PV操作的含義:PV操作是由P操作原語和V操作原語組成(原語是不可中斷的過程),對信號量進行操作,具體定義如下:

  P(S):①將信號量S的值減1,即S=S-1;

      ②如果S³0,則該進程繼續執行;否則該進程置爲等待狀態,排入等待隊列。

  V(S):①將信號量S的值加1,即S=S+1;

      ②如果S>0,則該進程繼續執行;否則釋放隊列中第一個等待信號量的進程。

P操作相當於申請資源,而V操作相當於釋放資源。

 

生產者-消費者問題是一個有代表性的進程同步問題,生產者-消費者問題,也稱作有界緩衝區問題,兩個進程共享一個公共的固定大小的緩衝區。其中一個是生產者,用於將消息放入緩衝區;另外一個是消費者,用於從緩衝區中取出消息。問題出現在當緩衝區已經滿了,而此時生產者還想向其中放入一個新的數據項的情形,或者當緩衝區空時,消費者還要從中取出數據項的問題。爲了保證這種情況不會發生,我們通常使用信號量和消息傳遞來解決生產者-消費者問題。

(1)使用信號量解決生產者-消費者問題
一個信號量的取值可以爲 0(表示沒有保存下來的喚醒操作)或者爲正值(表示有一個或多個喚醒操作)。
並且設立了兩種操作:down和 up(也是一般教科書上說的 P/V向量)。對一個信號量執行 down操作,表示檢查其值是否大於 0,如果該值大於 0,則將其值減 1(即用掉一個保存的喚醒信號)並繼續;如果爲 0,則進程休眠,而且此時 down操作並未結束。另外,就是檢查數值,修改變量值以及可能發生的休眠操作都作爲單一的,不可分割的原子操作來完成。

下面開始考慮用信號量來解決生產者-消費者問題了。
#define N 100                           // 緩衝區中的槽數目
typedef int semaphore;               // 信號量一般被定義爲特殊的整型數據
semaphore mutex = 1;               // 控制對臨界區的訪問
semaphore empty = N;               // 計數緩衝區中的空槽數目
semaphore full = 0;                 // 計數緩衝區中的滿槽數目

/* 生產者進程 */
void proceducer(void)
{
        int item;
        while(1)
        {
               item = procedure_item();       // 生成數據
               down(&empty);                              // 將空槽數目減 1
               down(&mutex);                              // 進入臨界區
               insert_item(item);                       // 將新數據放入緩衝區
               up(&mutex);                                      // 離開臨界區
               up(&full);                                      // 將滿槽的數目加 1
        }
}

/* 消費者進程 */
void consumer(voi)
{
        int item;
        while(1)
        {
               down(&full);                              // 將滿槽數目減 1
               down(&mutex);                              // 進入臨界區
               item = remove_item();               // 從緩衝區中取出數據項
               up(&mutex);                                      // 離開臨界區
               up(&empty);                                      // 將空槽數目加 1
               consumer_item(item);               // 處理數據項
        }
}

該解決方案使用了三個信號量:一個爲 full,用來記錄充滿的緩衝槽的數目,一個爲 empty,記錄空的緩衝槽總數,一個爲 mutex,用來確保生產者和消費者不會同時訪問緩衝區。mutex的初始值爲 1,供兩個或者多個進程使用的信號量,保證同一個時刻只有一個進程可以進入臨界區,稱爲二元信號量(binary semaphore)。如果每一個進程在進入臨界區前都執行一個 down(...),在剛剛退出臨界區時執行一個 up(...),就能夠實現互斥。

另外,通常是將 down和 up操作作爲系統調用來實現,而且 OS只需要在執行以下操作時暫時禁止全部中斷:測試信號量,更新信號量以及在需要時使某個進程休眠。

這裏使用了三個信號量,但是它們的目的卻不相同,其中 full和 empty用來同步(synchronization),而 mutex用來實現互斥。

(2)使用消息傳遞解決生產者-消費者問題
這種 IPC方式使用兩條原語 send和 receive,也是系統調用。如:
send(dest, &msg)       // 將消息 msg發送到目標(進程)dest中
receive(src, &msg)     // 接收由 src過來的 msg,如果沒有消息可用,則可能阻塞接收者

消息傳遞系統會面臨位於網絡中不同機器上的通信進程的情形,所以會更加的複雜。如:消息可能被網絡丟失,一般使用確認(ACK)消息。如果發送方在一定的時間段內沒有收到確認消息,則重發消息。

如果消息本身被正確接收,但是返回的 ACK消息丟失,發送方則重發消息,這樣接收方就會收到兩份同樣的消息。一般使用在每條原始消息的頭部嵌入一個連續的序號來解決這個問題。

另外,消息傳遞系統還需要解決進程命名的問題,在 send和 receive系統調用中指定的進程必須沒有二義性的。還有其他的一些問題,如性能問題,身份認證等等,不過那個就會扯多了,還是看看如果解決這個生產者-消費者的問題吧:

#define N 100                              // 緩衝區中的槽數目
/* 生產者進程 */
void proceducer(void)
{
        int item;
        messagemsg;                       // 消息緩衝區
        while(1)
        {
               item = procedure_item();       // 生成數據
               receive(consumer, &msg);       // 等待消費者發送空的緩衝區
               build_msg(&msg, item);               // 創建待發送消息
               send(consumer, &msg);               // 發送數據項給消費者
        }
}

/* 消費者進程 */
void consumer(voi)
{
        int item,i;
        messagemsg;
        for(i=0;i<N; i++)
               send(producer, &msg);               // 發送給生產者 N 個空緩衝區
        
        while(1)
        {
               receive(producer, &msg);       // 接收包含數據項的消息
               item = extract_item(&msg);       // 解析消息,並組裝成數據項
               send(proceduer, &msg);               // 然後又將空緩衝區發送回生產者
               consumer_item(item);               // 處理數據項
        }
}

在這個解決方案中,共使用了 N條消息,有點類似於上一個的共享內存緩衝區的 N個槽,消費者進程這邊首先通過一個 for循環將 N條空消息發送給生產者。當生產者向消費者傳遞一個數據項時,是通過取走每一條接收到的空消息,然後送回填充了內容的消息給消費者的。通過這種方式,整個消息傳遞系統中的總的消息數(包括空的消息 + 存了數據項的消息 == N)是不變的。

如果運行過程中,生產者進程的速度比消費者快,則所有的消息最終都會塞滿,然後生產者進程就會等待消費者(即使調用 procedure也是阻塞在 receive處),直到消費者返回一條空的消息;反之亦然。

下面再來看一下消息傳遞方式的兩種變體。一種是:爲每一個進程分配一個唯一的地址,讓消息按照這個進程的地址進行編址。也就是 send和 receive調用的第一個參數指定爲具體的進程地址。另一種是:引入信箱(mailbox),可以信箱就像一個盒子,裏面裝了很多的信件,這個信件就是我們要傳遞的消息,當然信箱是有容量限制的。當使用信箱時,send和 receive系統調用中的地址參數就是信箱的地址,而不是進程的地址。當一個進程嘗試向一個容量爆滿的信箱發送消息時,它將會被掛起,直到信箱中有消息被取走。

 

 

5.線程的實現方式. (也就是用戶線程與內核線程的區別)

線程的實現可分爲兩大類,用戶級線程(user-levelthread,ULT)和內核級線程(kernel-levelthread,KLT)。後者又稱爲內核支持的線程或輕量級進程

 

(1)用戶級線程

在一個純粹的用戶級線程軟件中,有關線程管理的所有工作都由應用程序完成,內核意識不到線程的存在。

使用用戶級線程而不是內核級線程的優點有:

  • 線程切換不需要內核態特權,進程並不需要爲了線程管理而切換到內核態 
  • 可以爲應用程序量身定做調度算法而不擾亂底層的操作系統調度程序 
  • 用戶級線程可以在任何操作系統中運行,不需要對底層內核進行修改以支持用戶級線程

相比內核級線程,用戶級線程有兩個明顯的缺點:

  • 許多系統調用都會引起阻塞,當用戶級線程執行一個系統調用時,不僅這個線程會被阻塞,進程中的所有線程都會被阻塞
  • 在純粹的用戶級線程策略中,一個多線程應用程序不能利用多處理技術

(2)內核級線程

在一個純粹的內核級線程軟件中,有關線程管理的所有工作都是由內核完成的,應用程序部分沒有進行線程管理的代碼,只有一個到內核線程設施的應用程序編程接口(API)。

 

該方法克服了用戶級線程方法的兩個基本缺陷:內核可以同時把同一個進程的多個線程調度到多個處理器中;如果進程中的一個線程被阻塞,內核可以調度同一個進程中的另一個線程。相比用戶級線程它的主要缺點是:把控制從一個線程傳送到進程中的另一個線程時,需要到內核的狀態切換。

 

某些操作系統採用組合用戶級線程和內核級線程的方法,同一個應用程序中的多個線程可以在多個處理器上並行的運行,某個會引起阻塞的系統調用不會阻塞整個進程。如果設計正確,該方法會結合兩種線程的優點,同時減少他們的缺點。

 

 

6.用戶態和核心態的區別。

當一個任務(進程)執行系統調用而陷入內核代碼中執行時,我們就稱進程處於內核運行態(或簡稱爲內核態)。此時處理器處於特權級最高的(0級)內核代碼中執行。當進程處於內核態時,執行的內核代碼會使用當前進程的內核棧。每個進程都有自己的內核棧。當進程在執行用戶自己的代碼時,則稱其處於用戶運行態(用戶態)。即此時處理器在特權級最低的(3級)用戶代碼中運行。

特權級顯然是非常有效的管理和控制程序執行的手段,因此在硬件上對特權級做了很多支持,就Intel x86架構的CPU來說一共有0~3四個特權級,0級最高,3級最低,硬件上在執行每條指令時都會對指令所具有的特權級做相應的檢查。雖然用戶態下和內核態下工作的程序有很多差別,但最重要的差別就在於特權級的不同,即權力的不同。運行在用戶態下的程序不能直接訪問操作系統內核數據結構和程序

當我們在系統中執行一個程序時,大部分時間是運行在用戶態下的,在其需要操作系統幫助完成某些它沒有權力和能力完成的工作時就會切換到內核態。

 用戶態和內核態的轉換

1)用戶態切換到內核態的3種方式

a. 系統調用

這是用戶態進程主動要求切換到內核態的一種方式,用戶態進程通過系統調用申請使用操作系統提供的服務程序完成工作,而系統調用的機制其核心還是使用了操作系統爲用戶特別開放的一箇中斷來實現,例如Linux的int 80h中斷。

b. 異常

當CPU在執行運行在用戶態下的程序時,發生了某些事先不可知的異常,這時會觸發由當前運行進程切換到處理此異常的內核相關程序中,也就轉到了內核態,比如缺頁異常。

c. 外圍設備的中斷

當外圍設備完成用戶請求的操作後,會向CPU發出相應的中斷信號,這時CPU會暫停執行下一條即將要執行的指令轉而去執行與中斷信號對應的處理程序,如果先前執行的指令是用戶態下的程序,那麼這個轉換的過程自然也就發生了由用戶態到內核態的切換。比如硬盤讀寫操作完成,系統會切換到硬盤讀寫的中斷處理程序中執行後續操作等。

 

這3種方式是系統在運行時由用戶態轉到內核態的最主要方式,其中系統調用可以認爲是用戶進程主動發起的,異常和外圍設備中斷則是被動的。

2)具體的切換操作

從觸發方式上看,可以認爲存在前述3種不同的類型,但是從最終實際完成由用戶態到內核態的切換操作上來說,涉及的關鍵步驟是完全一致的,沒有任何區別,都相當於執行了一個中斷響應的過程,因爲系統調用實際上最終是中斷機制實現的,而異常和中斷的處理機制基本上也是一致的,涉及到由用戶態切換到內核態的步驟主要包括:

[1] 從當前進程的描述符中提取其內核棧的ss0及esp0信息。

[2] 使用ss0和esp0指向的內核棧將當前進程的cs,eip,eflags,ss,esp信息保存起來,這個過程也完成了由用戶棧到內核棧的切換過程,同時保存了被暫停執行的程序的下一條指令。

[3] 將先前由中斷向量檢索得到的中斷處理程序的cs,eip信息裝入相應的寄存器,開始執行中斷處理程序,這時就轉到了內核態的程序執行了。

 

 

7.用戶棧和內核棧的區別。

(1.當進程運行在內核態時,CPU堆棧指針寄存器指向的是內核堆棧地址,使用的是內核堆棧。

當進程運行在用戶態時。CPU堆棧指針寄存器指向的是用戶堆棧地址,使用的是用戶堆棧。

 

當進程由於中斷進入內核態時,系統會把一些用戶態的數據信息保存到內核棧中,當返回到用戶態時,取出內核棧中得信息恢復出來,返回到程序原來執行的地方。
用戶棧就是進程在用戶空間時創建的棧,比如一般的函數調用,將會用到用戶棧。

 

(2.內核棧是屬於操作系統空間的一塊固定區域,可以用於保存中斷現場、保存操作系統子程序間相互調用的參數、返回值等。

用戶棧是屬於用戶進程空間的一塊區域,用戶保存用戶進程子程序間的相互調用的參數、返回值等。

(3.每個Windows 都有4g的進程空間,系統棧使用進程空間的低端部分,用戶棧是高端部分。如果用戶要直接訪問系統棧部分,需要有特殊的方式。

 

進程用戶棧和內核棧之間的切換

當進程由於中斷或系統調用從用戶態轉換到內核態時,進程所使用的棧也要從用戶棧切換到內核棧。系統調用實質就是通過指令產生中斷,稱爲軟中斷。進程因爲中斷(軟中斷或硬件產生中斷),使得CPU切換到特權工作模式,此時進程陷入內核態,進程進入內核態後,首先把用戶態的堆棧地址保存在內核堆棧中,然後設置堆棧指針寄存器的地址爲內核棧地址,這樣就完成了用戶棧向內核棧的切換。

當進程從內核態切換到用戶態時,最後把保存在內核棧中的用戶棧地址恢復到CPU棧指針寄存器即可,這樣就完成了內核棧向用戶棧的切換。

這裏要理解一下內核堆棧。前面我們講到,進程從用戶態進入內核態時,需要在內核棧中保存用戶棧的地址。那麼進入內核態時,從哪裏獲得內核棧的棧指針呢

要解決這個問題,先要理解從用戶態剛切換到內核態以後,進程的內核棧總是空的。這點很好理解,當進程在用戶空間運行時,使用的是用戶棧;當進程在內核態運行時,內核棧中保存進程在內核態運行的相關信息,但是當進程完成了內核態的運行,重新回到用戶態時,此時內核棧中保存的信息全部恢復,也就是說,進程在內核態中的代碼執行完成回到用戶態時,內核棧是空的。

因爲內核棧是空的,那當進程從用戶態切換到內核態後,把內核棧的棧頂地址設置給CPU的棧指針寄存器就可以了。

  

 

 8. 內存池、進程池、線程池。(c++程序員必須掌握)

  首先介紹一個概念“池化技術 ”。池化技術就是:提前保存大量的資源,以備不時之需以及重複使用。池化技術應用廣泛,如內存池,線程池,連接池等等。內存池相關的內容,建議看看Apache、Nginx等開源web服務器的內存池實現。
  由於在實際應用當做,分配內存、創建進程、線程都會設計到一些系統調用,系統調用需要導致程序從用戶態切換到內核態,是非常耗時的操作。因此,當程序中需要頻繁的進行內存申請釋放,進程、線程創建銷燬等操作時,通常會使用內存池、進程池、線程池技術來提升程序的性能。

  線程池:線程池的原理很簡單,類似於操作系統中的緩衝區的概念,它的流程如下:先啓動若干數量的線程,並讓這些線程都處於睡眠狀態,當需要一個開闢一個線程去做具體的工作時,就會喚醒線程池中的某一個睡眠線程,讓它去做具體工作,當工作完成後,線程又處於睡眠狀態,而不是將線程銷燬。

  進程池與線程池同理。

  內存池:內存池是指程序預先從操作系統申請一塊足夠大內存,此後,當程序中需要申請內存的時候,不是直接向操作系統申請,而是直接從內存池中獲取;同理,當程序釋放內存的時候,並不真正將內存返回給操作系統,而是返回內存池。當程序退出(或者特定時間)時,內存池纔將之前申請的內存真正釋放。

  

 

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

 可以把死鎖定義爲一組相互競爭系統資源或進行通信的進程間的“永久”阻塞。當一組進程中的每個進程都在等待某個事件(典型的情況是等待所請求的資源釋放),而只有在這組進程中的其他被阻塞的進程運行完畢後纔可以釋放該事件,這時就稱這組進程發生死鎖。因爲沒有事件能夠被觸發,所以死鎖是永久性的。

 

產生死鎖的原因主要是:

1) 因爲系統資源不足。

2) 進程運行推進的順序不合適。

3) 資源分配不當等

     

 

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

導致死鎖的4個必要條件:

1)互斥。一次只有一個進程可以使用一個資源。其他進程不能訪問已分配給其他進程的資源。

2)佔有且等待。當一個進程等待其他進程時,繼續佔有已經分配的資源。

3)不可搶佔。不能強行搶佔進程已佔有的資源。

4)循環等待。存在一個封閉的進程鏈,使得每個進程至少佔有此鏈中下一個進程所需要的一個資源。

 

 

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

1)死鎖預防

2)死鎖避免

3)死鎖檢測

4)一種綜合的死鎖策略

    所有的解決死鎖的策略都有其優缺點,在不同的情況下使用不同的策略比將操作系統機制設計爲只採用其中一種策略更有效。

  • 把資源分成幾組不同的資源類 
  • 爲預防在資源類之間由於循環等待產生死鎖,可使用線性排序策略 
  • 在一個資源類中,使用該類資源最適合的算法

作爲這種技術的一個例子,考慮下列資源類:

  • 可交換空間:在進程交換中所使用的外存中的存儲塊。對於可交換空間,通過要求一次性分配所有請求的資源來預防死鎖
  • 進程資源:可分配設備,如磁帶設備和文件。 對於這類資源,死鎖避免策略常常很有效,因爲進程可以事先聲明他們將需要的這類資源,採用資源排序的預防策略也是可能的
  • 內存:可以按頁或按段分配給進程。對於內存,基於搶佔的預防是最合適的策略。當一個進程被搶佔後,它僅僅是被換到外存,釋放空間以解決死鎖
  • 內部資源:諸如I/O通道。可以使用基於資源排序的預防策略

 

  

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

死鎖預防策略

在死鎖預防策略中,試圖設計一種系統來排除發生死鎖的可能性,方法分爲兩類:間接的死鎖預防方法(防止前面三個列出的三個必要條件中的任何一個的發生);直接的死鎖的預防方法(防止循環等待的發生)。

 

 

 

死鎖避免策略

   在死鎖預防中,通過約束資源請求,防止4個條件中至少一個的發生,可以通過直接或間接預防方法,但是這都會導致低效的資源使用和低效的進程執行

死鎖避免則相反,它允許前三個必要條件,但是通過明智的選擇,確保永遠不會到達死鎖點,因此死鎖避免比死鎖預防允許更多的併發。在死鎖避免中,是否允許當前資源分配請求是通過判斷該請求是否可能導致死鎖來決定的。因此,死鎖避免需要知道將來的進程資源請求的情況。

死鎖避免策略並不能確切的預測死鎖,它僅僅是預測死鎖的可能性並確保永遠不會出現這種可能性。

有兩種死鎖避免的辦法:

  • 如果一個進程的請求會導致死鎖,則不啓動此進程 
  • 如果一個進程增加的資源請求會導致死鎖,則不允許這次分配

 

銀行家算法:首先需要定義狀態和安全狀態的概念。系統的狀態是當前給進程分配的資源情況。因此,狀態包含兩個向量Resource(系統中每種資源的總量)和Available(未分配給進程的每種資源的總量)及兩個矩陣Claim(表示進程對資源的需求)和Allocation(表示當前分配給進程的資源)。安全狀態是指至少有一個資源分配序列不會導致死鎖。當進程請求一組資源時,假設同意該請求,從而改變了系統的狀態,然後確定其結果是否還處於安全狀態。如果是,同意這個請求;如果不是,阻塞該進程直到同意該請求後系統狀態仍然是安全的。

死鎖檢測策略

死鎖預防策略是非常保守的,他們通過限制訪問資源和在進程上強加約束來解決死鎖的問題。死鎖檢測則是完全相反,它不限制資源訪問或約束進程行爲,只要有可能,被請求的資源就被授權給進程操作系統週期性地執行一個算法檢測前面的循環等待的條件

 

 

 

13.進程調度算法。(週轉時間=程序結束時間--開始服務時間,帶權週轉時間=週轉時間/ 要求服務時間)

(1)先來先服務和短作業(進程)優先調度算法

1)先來先服務調度算法:先來先服務(FCFS)調度算法是一種最簡單的調度算法,該算法既可用於作業調度,也可用於進程調度。FCFS算法比較有利於長作業(進程),而不利於短作業(進程)。由此可知,本算法適合於CPU繁忙型作業,而不利於I/O繁忙型的作業(進程)。

 

2)短作業(進程)優先調度算法:短作業(進程)優先調度算法(SJ/PF)是指對短作業或短進程優先調度的算法,該算法既可用於作業調度, 也可用於進程調度。但其對長作業不利;不能保證緊迫性作業(進程)被及時處理;作業的長短只是被估算出來的。

 

(2)高優先權優先調度算法

1) 優先權調度算法的類型:爲了照顧緊迫性作業,使之進入系統後便獲得優先處理,引入了最高優先權優先(FPF)調度算法。此算法常被用在批處理系統中,作爲作業調度算法,也作爲多種操作系統中的進程調度,還可以用於實時系統中。當其用於作業調度,將後備隊列中若干個優先權最高的作業裝入內存。當其用於進程調度時,把處理機分配給就緒隊列中優先權最高的進程,此時,又可以進一步把該算法分成以下兩種:

非搶佔式優先權算法

搶佔式優先權調度算法(高性能計算機操作系統)

 

2)優先權類型 。對於最高優先權優先調度算法,其核心在於:它是使用靜態優先權還是動態優先權,以及如何確定進程的優先權。

 

3)高響應比優先調度算法

爲了彌補短作業優先算法的不足,我們引入動態優先權,使作業的優先等級隨着等待時間的增加而以速率a提高。 該優先權變化規律可描述爲:優先權=(等待時間+要求服務時間)/要求服務時間;即 =(響應時間)/要求服務時間

 

(3)基於時間片的輪轉調度算法

1)時間片輪轉法。時間片輪轉法一般用於進程調度,每次調度,把CPU分配隊首進程,並令其執行一個時間片。 當執行的時間片用完時,由一個記時器發出一個時鐘中斷請求,該進程被停止,並被送往就緒隊列末尾;依次循環。

 

2)多級反饋隊列調度算法

不必事先知道各種進程所需要執行的時間,它是目前被公認的一種較好的進程調度算法。 其實施過程如下:

a.設置多個就緒隊列,併爲各個隊列賦予不同的優先級。在優先權越高的隊列中,爲每個進程所規定的執行時間片就越小。

b.當一個新進程進入內存後,首先放入第一隊列的末尾,按FCFS原則排隊等候調度。 如果他能在一個時間片中完成,便可撤離;如果未完成,就轉入第二隊列的末尾,在同樣等待調度…… 如此下去,當一個長作業(進程)從第一隊列依次將到第n隊列(最後隊列)後,便按第n隊列時間片輪轉運行。

c.僅當第一隊列空閒時,調度程序才調度第二隊列中的進程運行;僅當第1到第(i-1)隊列空時, 纔會調度第i隊列中的進程運行,並執行相應的時間片輪轉。

d.如果處理機正在處理第i隊列中某進程,又有新進程進入優先權較高的隊列, 則此新隊列搶佔正在運行的處理機,並把正在運行的進程放在第i隊列的隊尾。

 

 

 

14.Windows內存管理的方式(塊式、頁式、段式、段頁式

Windows中的內存分爲兩類:

  • 物理內存即實際內存,實存儲器。 
  • 虛擬內存:用硬盤空間做內存來彌補計算機RAM空間的缺乏。

虛擬內存可行性的理論基礎:

(1)進程中的所有內存訪問地址都是邏輯地址,這些邏輯地址在運行時動態的被轉換爲物理地址,這意味着一個進程可以被換入或換出內存,使得進程可以執行過程中的不同時刻佔據內存中的不同區域。

(2)一個進程可以劃分成許多塊,在執行過程中,這些塊不需要連續的存放在內存中。

 

使用虛擬內存的好處:

1、在內存中保留多個進程。由於對任何特定的進程都僅僅裝入它的某些塊,因此就有足夠的空間來放置更多的進程。

2、進程可以比內存的全部空間還大。程序佔用的內存空間的大小是程序設計中最大的限制之一。通過基於分頁或分段的虛擬內存,這些分塊可以按某種覆蓋策略分別加載。

 

常用內存管理技術:

(1)固定分區

說明:在系統生成階段,內存被劃分成許多靜態分區。進程可以被裝入到大於或等於自身大小的分區。

優勢:實現簡單,只需要極少的操作系統開銷。

缺點:由於有內部碎片,對內存的使用不充分;活動進程的最大數目是固定的。

 

(2)動態分區

說明:分區是動態創建的,因而使得每個進程可以被裝入與自身大小正好相等的分區中。

優勢:沒有內部碎片;可以更充分的使用內存。

缺點:由於需要壓縮外部碎片,處理器利用率低。

 

(3)虛擬內存分頁

說明:內存被劃分爲許多大小相等的頁框;每個進程被劃分成許多大小與頁框相等的頁;不需要裝入一個進程的所有頁,每次只需將進程運行需要的頁裝入到內存中不一定連續的頁框中。非駐留頁在以後需要時自動調入內存。

優勢:沒有外部碎片;支持更高道數的多道程序設計;巨大的虛擬地址空間。

缺點:複雜的內存管理開銷。

 

使用分頁技術在內存中爲每個進程浪費的空間僅僅是進程最後一頁的一小部分形成的內部碎片,沒有任何外部碎片。

操作系統維護空閒頁框的列表,爲每個進程維護一個頁表,頁表給出了該進程的每一頁對應的頁框的位置,在程序中,每個邏輯地址包括一個頁號和在該頁中的偏移量。根據進程頁表中頁號和對應頁框的位置,由對應的頁框號和偏移量計算出物理地址。

 

(4)虛擬內存分段

說明:每個進程被劃分爲許多段;不需要裝入一個進程的所有頁,每次只需將進程運行需要的段裝入到內存中不一定連續的某些動態分區中;非駐留段在以後需要時自動調入內存。

優勢:沒有內部碎片;支持更高道數的多道程序設計;巨大的虛擬地址空間;支持保護與共享

缺點:複雜的內存管理開銷,分段消除了內部碎片,但是會產生外部碎片

 

在簡單的分段方案中,每個進程都有一個段表,系統也會維護一個內存中的空閒塊列表。每個段表項必須給出相應的段在內存中的起始地址,還必須指明段的長度,以確保不會使用無效的地址。

 

(5)段頁式

分段和分頁都有它們的長處。分頁對程序員是透明的,它消除了外部碎片,因而可以更有效地使用內存,並且移入或移出內存的塊是固定的,大小相等的。分段對程序員是可見的,它具有處理不斷增長的數據結構的能力以及支持共享和保護的能力。

 

在段頁式的系統中,用戶的地址空間被程序員劃分成許多段。每個段一次劃分成許多固定大小的頁,頁的長度等於內存中頁框的大小。從程序員的角度看,邏輯地址仍然由段號和段偏移量組成,從系統的角度看,段偏移量可視爲指定段中的一個頁號和頁偏移。

 

 

 

 

15. 內存連續分配方式採用的幾種算法及各自優劣。

常見內存分配算法及優缺點如下:
  (1)首次適應算法。使用該算法進行內存分配時,從空閒分區鏈首開始查找,直至找到一個能滿足其大小需求的空閒分區爲止。然後再按照作業的大小,從該分區中劃出一塊內存分配給請求者,餘下的空閒分區仍留在空閒分區鏈中。
  該算法傾向於使用內存中低地址部分的空閒分區,在高地址部分的空閒分區非常少被利用,從而保留了高地址部分的大空閒區。顯然爲以後到達的大作業分配大的內存空間創造了條件。缺點在於低址部分不斷被劃分,留下許多難以利用、非常小的空閒區,而每次查找又都從低址部分開始,這無疑會增加查找的開銷。
  (2)循環首次適應算法。該算法是由首次適應算法演變而成的。在爲進程分配內存空間時,不再每次從鏈首開始查找,而是從上次找到的空閒分區開始查找,直至找到一個能滿足需求的空閒分區,並從中劃出一塊來分給作業。該算法能使空閒中的內存分區分佈得更加均勻,缺點是將會缺乏大的空閒分區。
  (3)最佳適應算法。該算法總是把既能滿足需求,又是最小的空閒分區分配給作業。
  爲了加速查找,該算法需求將所有的空閒區按其大小排序後,以遞增順序形成一個空白鏈。這樣每次找到的第一個滿足需求的空閒區,必然是最優的。孤立地看,該算法似乎是最優的,但事實上並不一定。因爲每次分配後剩餘的空間一定是最小的,缺點是在存儲器中將留下許多難以利用的小空閒區。同時每次分配後必須重新排序,這也帶來了一定的開銷。
  (4)最差適應算法。最差適應算法中,該算法按大小遞減的順序形成空閒區鏈,分配時直接從空閒區鏈的第一個空閒分區中分配(不能滿足需要則不分配)。非常顯然,如果第一個空閒分區不能滿足,那麼再沒有空閒分區能滿足需要。這種分配方法初看起來不太合理,但他也有非常強的直觀吸引力:在大空閒區中放入程式後,剩下的空閒區常常也非常大,於是還能裝下一個較大的新程式。
  最壞適應算法和最佳適應算法的排序正好相反,他的隊列指針總是指向最大的空閒區,在進行分配時,總是從最大的空閒區開始查尋。
  該算法克服了最佳適應算法留下的許多小的碎片的不足,但缺點是保留大的空閒區的可能性減小了,而且空閒區回收也和最佳適應算法相同複雜。

 

  

 

16. 動態鏈接及靜態鏈接

靜態鏈接就是在編譯鏈接時直接將需要的執行代碼拷貝到調用處,優點就是在程序發佈的時候就不需要的依賴庫,也就是不再需要帶着庫一塊發佈,程序可以獨立執行,但是體積可能會相對大一些。

動態鏈接就是在編譯的時候不直接拷貝可執行代碼,而是通過記錄一系列符號和參數,在程序運行或加載時將這些信息傳遞給操作系統,操作系統負責將需要的動態庫加載到內存中,然後程序在運行到指定的代碼時,去共享執行內存中已經加載的動態庫可執行代碼,最終達到運行時連接的目的。優點是多個程序可以共享同一段代碼,而不需要在磁盤上存儲多個拷貝,缺點是由於是運行時加載,可能會影響程序的前期執行性能。

 

動態鏈接庫的兩種鏈接方法:

(1) 裝載時動態鏈接(Load-time Dynamic Linking):這種用法的前提是在編譯之前已經明確知道要調用DLL中的哪幾個函數,編譯時在目標文件中只保留必要的鏈接信息,而不含DLL函數的代碼;當程序執行時,調用函數的時候利用鏈接信息加載DLL函數代碼並在內存中將其鏈接入調用程序的執行空間中(全部函數加載進內存),其主要目的是便於代碼共享。(動態加載程序,處在加載階段,主要爲了共享代碼,共享代碼內存)

(2) 運行時動態鏈接(Run-time Dynamic Linking):這種方式是指在編譯之前並不知道將會調用哪些DLL函數,完全是在運行過程中根據需要決定應調用哪個函數,將其加載到內存中(只加載調用的函數進內存),並標識內存地址,其他程序也可以使用該程序,並用LoadLibrary和GetProcAddress動態獲得DLL函數的入口地址。(dll在內存中只存在一份,處在運行階段)

上述的區別主要在於階段不同,編譯器是否知道進程要調用的dll函數。動態加載在編譯時知道所調用的函數,而在運行態時則必須不知道。

 

 

 

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

基本分頁儲存管理方式具有如下特徵:
1) 一次性。要求將作業全部裝入內存後方能運行。許多作業在每次運行時,並非其全部程序和數據都要用到。如果一次性地裝入其全部程序,造成內存空間的浪費。

2) 駐留性。作業裝入內存後,便一直駐留在內存中,直至作業運行結束。儘管運行中的進程會因I/O而長期等待,或有的程序模塊在運行過一次後就不再需要(運行)了,但它們都仍將繼續佔用寶貴的內存資源。


請求分頁儲存管理

它是實現虛擬存儲器的一種常用方式,它是在基本分頁儲存管理的基礎上實現的。其基本思想是:在進程開始運行之前,僅裝入當前要執行的部分頁面即可運行;在執行過程中,可使用請求調入中斷動態裝入要訪問但又不在內存的頁面;當內存空間已滿,而又需要裝入新的頁面時,者根據置換功能適當調出某個頁面,以便騰出空間而裝入新的頁面。爲實現請求分頁,需要一定的硬件支持,包括:頁表機制、缺頁中斷機構、地址變換機構。

 

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

分頁管理方式是從計算機的角度考慮設計的,以提高內存的利用率,提高計算機的性能,提升計算機的性能,且分頁通過硬件機制實現,對用戶完全透明;

而分段管理方式的提出則是考慮用戶和程序員,以滿足方便編程、信息保護和共享、動態增長及動態鏈接等多方面的需要。

 

基本分段儲存管理:

段式管理方式是按照用戶進程中的自然段劃分邏輯空間。例如,用戶進程由主程序、兩個子程序、棧和一段數據組成,於是可以把這個用戶進程劃分爲5個段,每段從0開始編址,並分配一段連續的地址空間(段內要求連續,段間不要求連續,因此整個作業的地址空間是二維的)。其邏輯地址由段號S與段內偏移量W兩部分組成。

與分頁管理類似,分段管理的保護方法主要有兩種:一種是存取控制保護,另一種是地址越界保存。地址越界保護是利用段表寄存器中的段表長度與邏輯地址中的段號比較,若段號大於段表長度則產生越界中斷;再利用段表項中的段長和邏輯地址中的段內位移進行比較,若段內位移大於段長,也會產生越界中斷。

 

基本分段儲存管理方式就像基本分頁儲存管理方式一樣,將作業需要的數據段一次性的全部裝入內存中,作業裝入內存後,便一直駐留在內存中,直至作業運行結束。

 

請求分段儲存管理方式就如同請求分頁儲存管理方式一樣,在進程開始運行之前,僅裝入當前要執行的部分段即可運行;在執行過程中,可使用請求調入中斷動態裝入要訪問但又不在內存的程序段;當內存空間已滿,而又需要裝入新的段時,根據置換功能適當調出某個段,以便騰出空間而裝入新的段。

 

 

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

分段和分頁其實都是一種對地址的劃分或者映射的方式。 兩者的區別主要有以下幾點:

 

1)頁是信息的物理單位,分頁是爲實現離散分配方式,以消減內存的外零頭,提高內存的利用率;或者說,分頁僅僅是由於系統管理的需要,而不是用戶的需要(也是對用戶透明的)。段是信息的邏輯單位,它含有一組其意義相對完整的信息(比如數據段、代碼段和堆棧段等)。分段的目的是爲了能更好的滿足用戶的需要(用戶也是可以使用的)。

 

2)頁的大小固定且由系統確定,把邏輯地址劃分爲頁號和頁內地址兩部分,是由機器硬件實現的,因而一個系統只能有一種大小的頁面。段的長度卻不固定,決定於用戶所編寫的程序,通常由編輯程序在對源程序進行編輯時,根據信息的性質來劃分。

 

3)分頁的作業地址空間是維一的,即單一的線性空間,程序員只須利用一個記憶符(線性地址的16進製表示),即可表示一地址。分段的作業地址空間是二維的,程序員在標識一個地址時,既需給出段名(比如數據段、代碼段和堆棧段等),又需給出段內地址。

 

4)頁和段都有存儲保護機制。但存取權限不同:段有讀、寫和執行三種權限;而頁只有讀和寫兩種權限

 

 

 

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

 

1)最佳置換算法(OPT)(OPTimalreplacement理想置換算法)
這是一種理想情況下的頁面置換算法,但實際上是不可能實現的。該算法的基本思想是:發生缺頁時,有些頁面在內存中,其中有一頁將很快被訪問(也包含緊接着的下一條指令的那頁),而其他頁面則可能要到10、100或者1000條指令後纔會被訪問,每個頁面都可以用在該頁面首次被訪問前所要執行的指令數進行標記。最佳頁面置換算法只是簡單地規定:標記最大的頁應該被置換,選擇下次訪問距當前時間最長的那些頁。這個算法唯一的一個問題就是它無法實現。當缺頁發生時,操作系統無法知道各個頁面下一次是在什麼時候被訪問。雖然這個算法不可能實現,但是最佳頁面置換算法可以用於對可實現算法的性能進行衡量比較。

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

3)最近最久未使用(LRU)算法
FIFO算法和OPT算法之間的主要差別是,FIFO算法利用頁面進入內存後的時間長短作爲置換依據,而OPT算法的依據是將來使用頁面的時間。如果以最近的過去作爲不久將來的近似,那麼就可以把過去最長一段時間裏不曾被使用的頁面置換掉。它的實質是,當需要置換一頁時,選擇在最近一段時間裏最久沒有使用過的頁面予以置換。這種算法就稱爲最久未使用算法(Least Recently Used,LRU)。
LRU算法是與每個頁面最後使用的時間有關的。當必須置換一個頁面時,LRU算法選擇過去一段時間裏最久未被使用的頁面。雖然LRU策略的性能接近OPT策略,但是問題在於這種策略比較難實現。

 

 

21. 虛擬內存的定義及實現方式。

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

 

 

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

1)併發(concurrence)

並行性與併發性這兩個概念是既相似又區別的兩個概念。並行性是指兩個或者多個事件在同一時刻發生,這是一個具有微觀意義的概念,即在物理上這些事件是同時發生的;而併發性是指兩個或者多個事件在同一時間的間隔內發生,它是一個較爲宏觀的概念。在多道程序環境下,併發性是指在一段時間內有多道程序在同時運行,但在單處理機的系統中,每一時刻僅能執行一道程序,故微觀上這些程序是在交替執行的。   

應當指出,通常的程序是靜態實體,它們是不能併發執行的。爲了使程序能併發執行,系統必須分別爲每個程序建立進程。進程,又稱任務,簡單來說,是指在系統中能獨立運行並作爲資源分配的基本單位,它是一個活動的實體。多個進程之間可以併發執行和交換信息。一個進程在運行時需要運行時需要一定的資源,如cpu,存儲空間,及i/o設備等。在操作系統中引入進程的目的是使程序能併發執行。

 

2)共享 (sharing)

所謂共享是指,系統中的資源可供內存中多個併發執行的進程共同使用。由於資源的屬性不同,故多個進程對資源的共享方式也不同,可以分爲:互斥共享方式同時訪問方式。

 

3)虛擬 (virtual)

是指通過技術把一個物理實體變成若干個邏輯上的對應物。在操作系統中虛擬的實現主要是通過分時的使用方法。顯然,如果n是某一個物理設備所對應的虛擬邏輯設備數,則虛擬設備的速度必然是物理設備速度的1/n。

 

4)異步 (asynchronism)

在多道程序設計環境下,允許多個進程併發執行,由於資源等因素的限制,通常,進程的執行並非“一氣呵成”,而是以“走走停停”的方式運行。內存中每個進程在何時執行,何時暫停,以怎樣的方式向前推進,每道程序總共需要多少時間才能完成,都是不可預知的。或者說,進程是以一步的方式運行的。儘管如此,但只要運行環境相同,作業經過多次運行,都會獲得完全相同的結果。

 

 

 

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技術(Simultaneous Peripheral Operating On Line)

同時聯機外圍操作技術,它是關於慢速字符設備如何與計算機主機進行數據交換的一種技術,通常又稱假脫機技術。

在多道程序環境下,利用多道程序中的一道或者兩道程序來模擬脫機輸入/輸出中的外圍控制機的功能,以達到“脫機”輸入/輸出的目的。

利用這種技術可把獨佔設備轉變成共享的虛擬設備,從而提高獨佔設備的利用率和進程的推進速度。

 

 

SPOOLING系統 是對脫機輸入/輸出工作的模擬,它必須有大容量的且可隨機存取的存儲器
的支持。

其主要思想是在聯機的條件下,進行兩個方向的操作,在數據輸入時,將數據從輸入設備傳送到磁盤或磁帶(塊設備),然後把這些塊設備與主機相連;反過來,在數據輸出時,將輸出數據傳送到磁盤或磁帶上,再從磁盤或磁帶傳送到輸出設備。

這樣,可以將一臺獨佔的物理設備虛擬爲並行使用的多態邏輯設備,從而使該物理設備被多個進程共享。


輸入進程SPI是模擬脫機輸入時的外圍控制機,它將用戶要求處理的數據從輸入設備通過輸入緩衝區再送到輸入井(磁盤上開闢的一塊區域),當CPU處理這些數據數據時,就直接從輸入井讀入內存。

輸出進程SPO是模擬脫機輸出時的外圍控制機,把用戶要求輸出的數據,先從內存送到輸出井,待輸出設備空閒時,再將輸出井中的數據通過輸出緩衝區(內存中一塊區域)傳送到輸出設備上。

 

實例——利用打印機實現打印機共享

已經被廣泛用於多用戶系統和計算機網絡中,它實際上就是利用SPOOLING技術將獨佔的打印機改造爲一臺供做個用戶共享的設備,只要有足夠的外存空間和多道程序操作系統的支持即可。

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

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

 

  

 

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

外存,指的是除了cpu緩存和內存以外的存儲器,硬盤、光盤、U盤都可以被稱爲外存。所有的數據,也都存在這裏面,故他的分配方式變得極其重要,這直接影響到了計算機的運行速度。

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

 

(1) 連續分配

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

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

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

    如圖:

    

 

    

(2)鏈式分配

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

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

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

    如圖:

   

 

(3)索引分配

    原理:每個文件在FAT中有一個一級索引,索引包含分配給文件的每個分區的入口。文件的索引保存在單獨的一個塊中,FAT中該文件的入口指向這一塊。

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

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

    如圖:

   

    

(4)連續分配和索引分配相結合

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

    文件的直接訪問:使用連續分配方式。

    文件的順序訪問:採用鏈接分配。

    對於這些系統,所使用的訪問類型,必須在文件創建時加以說明。

 

(5)多重索引

    原理:首先,多重索引也是索引分配的一種,只不過它是將一個大文件的所有索引表(二級索引)的地址放在另一個索引表(一級索引)中。ps:跟數據庫第四範式非常像。

   

    大文件:設一個盤塊大小爲1kb,長度100kb的文件就需要100個盤塊,索引表至少需要100項;若文件大小爲1000kb,則索引表項就要有1000項。設盤塊號用4個字節表示,則該索引表至少佔用4000bye(約4k)。

    當文件很大時,存在的問題:1.需要很多磁盤塊。2.索引表很大。3.不能將整個索引表放在內存。

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

    如圖:

   

    多重索引表結構圖示:

   

 

說明:題目來源於網絡上看到的IT體系結構知識一文,作者未知。這些知識點的解答結合了書本和網絡上許多優秀的博客的內容,如內容有誤,望指正。這篇文章僅供自己和有需要的人蔘考學習之用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章