操作系統常見面試題

1、什麼是進程(Process)和線程(Thread)?有何區別?

(1)進程是併發程序在一個數據集合上的一次執行過程,進程是系統進行資源分配和調度的獨立單位線程是進程的一個實體,是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己不擁有任何系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧)但是它可以訪問其隸屬進程的全部資源。

(2)線程是進程的一個實體,一個進程可以擁有多個線程,多個線程也可以併發執行。一個沒有線程的進程也可以看做是單線程的,同樣線程也經常被看做是一種輕量級的進程。並且進程可以不依賴於線程而單獨存在,而線程則不然。

(3) 與進程的控制表PCB相似,線程也有自己的控制表TCB,但是TCB中所保存的線程狀態比PCB表少得多。

進程的作用與定義:是爲了提高CPU的執行效率,爲了避免因等待而造成CPU空轉以及其他計算機硬件資源的浪費而提出來的。

線程的引入:例如,有一個Web服務器要進程的方式併發地處理來自不同用戶的網頁訪問請求的話,可以創建父進程和多個子進程的方式來進行處理,但是創建一個進程要花費較大的系統開銷和佔用較多的資源。除外,這些不同的用戶子進程在執行的時候涉及到進程上下文切換,上下文切換是一個複雜的過程。所以,爲了減少進程切換和創建的開銷,提高執行效率和節省資源,人們在操作系統中引入了"線程(thread)"的概念。


2.進程的通訊方式

進程間通訊的方式:

  • 管道有命名管道和非命名管道之分,非命名管道只能用於父子進程通訊,命名管道可用於非父子進程,命名管道就是FIFO,管道是先進先出的通訊方式。FIFO是一種先進先出的隊列。它類似於一個管道,只允許數據的單向流動。每個FIFO都有一個名字,允許不相關的進程訪問同一個FIFO,因此也成爲命名管。
  • 消息隊列:是用於兩個進程之間的通訊,首先在一個進程中創建一個消息隊列,然後再往消息隊列中寫數據,而另一個進程則從那個消息隊列中取數據。需要注意的是,消息隊列是用創建文件的方式建立的,如果一個進程向某個消息隊列中寫入了數據之後,另一個進程並沒有取出數據,即使向消息隊列中寫數據的進程已經結束,保存在消息隊列中的數據並沒有消失,也就是說下次再從這個消息隊列讀數據的時候,就是上次的數據!!!
  • 信號量, 不能傳遞複雜消息,只能用來同步
  • 共享內存,只要首先創建一個共享內存區,其它進程按照一定的步驟就能訪問到這個共享內存區中的數據,當然可讀可寫;

幾種方式的比較:

  • 管道:速度慢,容量有限
  • 消息隊列:容量受到系統限制,且要注意讀的時候,要考慮上一次沒有讀完數據的問題。
  • 信號量:不能傳遞複雜消息,只能用來同步
  • 共享內存區:能夠很容易控制容量,速度快,但要保持同步,比如一個進程在寫的時候,另一個進程要注意讀寫的問題,相當於線程中的線程安全,當然,共享內存區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了一塊內存的。


3.線程同步的方式

  • 臨界區:通過對多線程的串行化來訪問公共資源或者一段代碼,速度快,適合控制數據訪問
  • 互斥量:採用互斥對象機制,只有擁有互斥對象的線程纔有訪問公共資源的權限,因爲互斥對象只有一個,所以可以保證公共資源不會同時被多個線程訪問
  • 信號量:它允許多個線程同一時刻訪問同一資源,但是需要限制同一時刻訪問此資源的最大線程數目。信號量對象對線程的同步方式與前面幾種方法不同,信號允許多個線程同時使用共享資源,這與操作系統中PV操作相似。
  • 事件(信號):通過通知操作的方式來保持多線程的同步,還可以方便的實現多線程的優先級比較的操作

總結比較: 

  • 互斥量與臨界區的作用非常相似,但互斥量是可以命名的,也就是說它可以跨越進程使用。所以創建互斥量需要的資源更多,所以如果只爲了在進程內部是用的話使用臨界區會帶來速度上的優勢並能夠減少資源佔用量。因爲互斥量是跨進程的互斥量一旦被創建,就可以通過名字打開它。
  • 互斥量(Mutex),信號燈(Semaphore),事件(Event)都可以被跨越進程使用來進行同步數據操作,而其他的對象與數據同步操作無關,但對於進程和線程來講,如果進程和線程在運行狀態則爲無信號狀態,在退出後爲有信號狀態。所以可以使用WaitForSingleObject來等待進程和線程退出。
  • 通過互斥量可以指定資源被獨佔的方式使用,但如果有下面一種情況通過互斥量就無法處理,比如現在一位用戶購買了一份三個併發訪問許可的數據庫系統,可以根據用戶購買的訪問許可數量來決定有多少個線程/進程能同時進行數據庫操作,這時候如果利用互斥量就沒有辦法完成這個要求,信號燈對象可以說是一種資源計數器。

4.ThreadLocal和其他同步機制的比較

Threadlocal和其他所有的同步機制都是爲了解決多線程中的對同一變量的訪問衝突,在普通的同步機制中,是通過對對象加鎖來實現多個線程對同一變量的安全訪問的。這時該變量是多個線程共享的,使用這種同步機制需要很細緻的分析在什麼時候對變量進行讀寫,什麼時候需要鎖定某個對象,什麼時候釋放該對象的索等等。所有這些都是因爲多個線程共享了該資源造成的。

Threadlocal就從另一個角度來解決多線程的併發訪問,Threadlocal會爲每一個線程維護一個和該線程綁定的變量副本,從而隔離了多個線程的數據共享,每一個線程都擁有自己的變量副本,從而也就沒有必要對該變量進行同步了。ThreadLocal提供了線程安全的共享對象,在編寫多線程代碼時,可以把不安全的變量封裝進ThreadLocal。

總結:當然ThreadLocal並不能替代同步機制,兩者面向的問題領域不同。同步機制是爲了同步多個線程對相同資源的併發訪問,是爲了多個線程之間進行通信的有效方式;而ThreadLocal是隔離多個線程的數據共享,從根本上就不在多個線程之間共享資源(變量),這樣當然不需要對多個線程進行同步了。所以,如果你需要進行多個線程之間進行通信,則使用同步機制;如果需要隔離多個線程之間的共享衝突,可以使用ThreadLocal,這將極大地簡化你的程序,使程序更加易讀、簡潔。


5.關於死鎖的問題

首先回答死鎖的定義,所謂死鎖就是一個進程集合中的多個進程因爲競爭資源,而造成的互相等待現象

死鎖的原因:系統資源不足;多個進程的推進順序不合理

死鎖的必要條件:

  • 互斥條件(Mutual exclusion):資源不能被共享,只能由一個進程使用。
  • 請求與保持條件(Hold and wait):已經得到資源的進程可以再次申請新的資源。
  • 非剝奪條件(No pre-emption):已經分配的資源不能從相應的進程中被強制地剝奪。
  • 循環等待條件(Circular wait):系統中若干進程組成環路,改環路中每個進程都在等待相鄰進程正佔用的資源。

處理死鎖的策略:

(1) 死鎖預防破壞導致死鎖必要條件中的任意一個就可以預防死鎖。例如,要求用戶申請資源時一次性申請所需要的全部資源,這就破壞了保持和等待條件;將資源分層,得到上一層資源後,才能夠申請下一層資源,它破壞了環路等待條件。預防通常會降低系統的效率。

(2) 死鎖避免:避免是指進程在每次申請資源時判斷這些操作是否安全,例如,使用銀行家算法。死鎖避免算法的執行會增加系統的開銷。

(3) 死鎖檢測死鎖預防和避免都是事前措施,而死鎖的檢測則是判斷系統是否處於死鎖狀態,如果是,則執行死鎖解除策略。

(4) 死鎖解除:這是與死鎖檢測結合使用的,它使用的方式就是剝奪。即將某進程所擁有的資源強行收回,分配給其他的進程。  


兩個相關算法:

鴕鳥算法(即無視死鎖,不去處理):

該算法可以應用在極少發生死鎖的的情況下。爲什麼叫鴕鳥算法呢,因爲傳說中鴕鳥看到危險就把頭埋在地底下,可能鴕鳥覺得看不到危險也就沒危險了吧。跟掩耳盜鈴有點像。

銀行家算法

 所謂銀行家算法,是指在分配資源之前先看清楚,資源分配後是否會導致系統死鎖。如果會死鎖,則不分配,否則就分配。

按照銀行家算法的思想,當進程請求資源時,系統將按如下原則分配系統資源:

(1) 當一個進程對資源的最大需求量不超過系統中的資源數時可以接納該進程。

(2) 進程可以分期請求資源,當請求的總數不能超過最大需求量。

(3) 當系統現有的資源不能滿足進程尚需資源數時,對進程的請求可以推遲分配,但總能使進程在有限的時間裏得到資源。

(4) 當系統現有的資源能滿足進程尚需資源數時,必須測試系統現存的資源能否滿足該進程尚需的最大資源數,若能滿足則按當前的申請量分配資源,否則也要推遲分配。


6.物理地址,邏輯地址,分頁,分段

參考 http://www.cnblogs.com/felixfang/p/3420462.html ,有很好的解釋。

另附例題:http://blog.csdn.net/lzx_322/article/details/9209157


7.中斷和輪詢

中斷和輪詢的特點

  對I/O設備的程序輪詢的方式,是早期的計算機系統對I/O設備的一種管理方式。它定時對各種設備輪流詢問一遍有無處理要求。輪流詢問之後,有要求的,則加以處理。在處理I/O設備的要求之後,處理機返回繼續工作。儘管輪詢需要時間,但輪詢要比I/O設備的速度要快得多,所以一般不會發生不能及時處理的問題。當然,再快的處理機,能處理的輸入輸出設備的數量也是有一定限度的。而且,程序輪詢畢竟佔據了CPU相當一部分處理時間,因此,程序輪詢是一種效率較低的方式,在現代計算機系統中已很少應用。

  程序中斷通常簡稱中斷,是指CPU在正常運行程序的過程中,由於預先安排或發生了各種隨機的內部或外部事件,使CPU中斷正在運行的程序,而轉到爲響應的服務程序去處理。

  輪詢——效率低,等待時間很長,CPU利用率不高。

  中斷——容易遺漏一些問題,CPU利用率高。


8.操作系統的優先級反轉

      優先級反轉是指一個低優先級的任務持有一個被高優先級任務所需要的共享資源。高優先任務由於因資源缺乏而處於受阻狀態,一直等到低優先級任務釋放資源爲止。而低優先級獲得的CPU時間少,如果此時有優先級處於兩者之間的任務,並且不需要那個共享資源,則該中優先級的任務反而超過這兩個任務而獲得CPU時間。如果高優先級等待資源時不是阻塞等待,而是忙循環,則可能永遠無法獲得資源,因爲此時低優先級進程無法與高優先級進程爭奪CPU時間,從而無法執行,進而無法釋放資源,造成的後果就是高優先級任務無法獲得資源而繼續推進。

      優先級反轉的解決辦法:

(1)設置優先級上限:給臨界區一個高優先級,進入臨界區的進程都將獲得這個高優先級,如果其他試圖進入臨界區的進程的優先級都低於這個高優先級【這裏是爲了給原來的低優先級任務分配更多的時間片】,那麼優先級反轉就不會發生。
(2)優先級繼承:當一個高優先級進程等待一個低優先級進程持有的資源時,低優先級進程將暫時獲得高優先級進程的優先級別,在釋放共享資源後,低優先級進程回到原來的優先級別。嵌入式系統VxWorks就是採用這種策略。



9.資源調度算法

(1)實質是資源分配(分配CPU)的方式。

(2)分類

先來先服務算法

思想:總是選擇一個最先進入隊列的進程,爲之分配處理器,一直到進程執行結束或者阻塞而放棄處理機。

特點:屬於非搶佔式調度。

缺點:

1. 僅考慮進程的等待時間,有利於長進程,不利於短進程。

2. 實時性不好,未考慮進程的緊迫程度。

影響:會導致短進程(執行時間短)等待時間太長,使得短進程的週轉時間太長(執行時間 - 到達時間)。

評價:先來先服務算法有利於CPU繁忙型(執行時間長)的進程,而不利於IO繁忙型(執行時間短)的進程。

短作業優先算法

思想:總是先執行運行時間短的進程。

特點:可以是搶佔式調度,也可以是非搶佔式調度。

缺點:

1. 進考慮進程的運行時間,對長進程不利,會出現長進程餓死現象。

2.實時性不好,未考慮進程的緊迫程度。

3.進程的運行時間是估計值,不能準確衡量短進程。

優點:能有效地降低所有進程的平均等待時間,提高系統的吞吐量。

(體現在數據上,其實就是降低短進程的等待時間,使得進程的平均週轉時間和平均等待時間都降低)。

高優先權優先調度算法

思想:總是先執行優先級高的進程。

特點:可以是搶佔式調度,也可以是非搶佔式調度。

分類:根據獲得優先權時間可以分爲兩類:

1.靜態優先權

特點:創建進程時分配。

優點:簡單易行,系統開銷小。

缺點:不夠精確,而且很可能出現優先權低的進程得不到調度的情況(餓死)

2.動態優先權

特點:進程的優先權能夠隨着進程的推進和等待時間而改變。

典型代表:高響應比優先調度算法。

進程優先級 = 1 + (等待時間 / 要求服務時間)。

優點:折中了短作業優先 + 先來先服務。即照顧短進程,又考慮進程到達的先後順序,不會使得作業長期得不到服務。

基於時間片的輪轉算法

思想:先來先服務 + 時間片輪轉。

特點:搶佔式調度(執行不完,也得閃人)。

多級反饋隊列調度算法

思想:

1.在多個隊列間,屬於高優先級優先調度。

2.在隊列內,屬於先來先服務 + 時間片輪轉。

特點:搶佔式調度

優點:不必知道各個進程需要的執行時間,而且還可以滿足各種類型的進程的需要。

硬件設置:

1. 設置多個就緒隊列,

2. 在不同的隊列間設置不同的優先級,且優先級下降(越下面的隊列優先級越小)。

3. 在不同的隊列內設置不同的時間片,且時間片上升(越下面的隊列中時間片越長)。

工作方式:

1. 新進程進入第一隊列末尾,按先來先服務排隊等待調度。

2. 能在一個時間片內執行完,則可以直接離開os,不能在時間片執行完,在放入第二隊列。...。

3. 若到最後一個隊列仍沒有執行完,則放到本隊列的隊尾,繼續循環執行。

注意:

1. 當前i-1個隊列爲空時,才能調度第i個隊列的進程

2. 若第i個隊列中的進程A正在執行,但是有進程B進入第1個隊列,此時進程A被強佔了CPU,之後應該放到所在隊列的隊尾,等待執行。注意,不是放入下一隊列


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