操作系統常問的面試題目

操作系統常問的面試題目

  • linux進程fork複製了父進程的哪些資源

fork採用了寫時複製技術,而寫時複製的核心是:只有進程空間的各段的內容要發生變化時,纔會將父進程的內容複製一份給子進程。故剛開始只複製了父進程的頁表以及給子進程創建進程描述符。

具體詳細細節見https://blog.csdn.net/hycxag/article/details/83048446

  • 孤兒進程,殭屍進程,守護進程的含義

  • 孤兒進程:如果父進程先退出,子進程還沒退出那麼子進程將被 託孤給init進程,這是子進程的父進程就是init進程(1號進程)。
  • 殭屍進程:進程終止後進入僵死狀態(zombie),等待告知父進程自己終止,後才能完全消失.但是如果一個進程已經終止了,但是其父進程還沒有獲取其狀態,那麼這個進程就稱之爲殭屍進程.殭屍進程還會消耗一定的系統資源,並且還保留一些概要信息供父進程查詢子進程的狀態可以提供父進程想要的信息.一旦父進程得到想要的信息,殭屍進程就會結束
  • 守護進程:就是在後臺運行,不與任何終端關聯的進程,通常情況下守護進程在系統啓動時就在運行,它們以root用戶或者其他特殊用戶(apache和postfix)運行,並能處理一些系統級的任務.習慣上守護進程的名字通常以d結尾(sshd)。

守護進程的創建步驟:

  • 調用fork(),創建新進程,它會是將來的守護進程.
  • 在父進程中調用exit,保證子進程不是進程組長
  • 調用setsid()創建新的會話區
  • 將當前目錄改成跟目錄(如果把當前目錄作爲守護進程的目錄,當前目錄不能被卸載他作爲守護進程的工作目錄)
  • 將標準輸入,標註輸出,標準錯誤重定向到/dev/null
  • 如何避免殭屍進程

  1. fork twice。使用場景:一個進程任務很長,另一個進程任務很短。
  2. 父進程調用wait()方法,但是會使父進程阻塞
  3. signal(sigchld,sig_ign)。通過signal(SIGCHLD, SIG_IGN)通知內核對子進程的結束不關心,由內核回收,即可讓內核把殭屍子進程轉交給init進程去處理,省去了大量殭屍進程佔用系統資源。
  4. 在signal handler函數中調用 waitpid
  5. 讓殭屍進程變成孤兒進程,由init回收,就是讓父親先死

具體想找細節見https://blog.csdn.net/hycxag/article/details/83049908

  • 進程與線程的區別

線程是指進程內的一個執行單元,也是進程內的可調度實體;進程在執行過程中擁有獨立的內存單元。他們之間的區別:

  1. 調度:線程作爲調度和分配的基本單位,進程作爲擁有資源的基本單位。
  2. 併發性:不僅進程之間可以併發執行,同一個進程的多個線程之間也可併發執行。
  3. 擁有資源:進程是擁有資源的一個獨立單位,線程不擁有系統資源,但可以訪問隸屬於進程的資源。
  4. 系統開銷:在創建或撤消進程時,由於系統都要爲之分配和回收資源,導致系統的開銷明顯大於創建或撤消線程時的開銷。
  • 進程間通信方式

  1. 管道:管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程之間使用。進程的親緣關係通常是指父子進程關係。
  2. 有名管道(FIFO):有名管道也是半雙工的通信方式,但是允許在沒有親緣關係的進程之間使用,管道是先進先出的通信方式。
  3. 信號量:信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
  4. 消息隊列:消息隊列是有消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
  5. 信號 ( sinal ) :信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
  6. 共享內存( shared memory ) :共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號量,配合使用,來實現進程間的同步和通信。
  7. 套接字( socket ) :套接字也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同機器間的進程通信。
  • 多線程如何同步

臨界區、互斥區、事件、信號量四種方式

  1. 臨界區:通過對多線程的串行化來訪問公共資源或一段代碼,速度快,適合控制數據訪問。在任意時刻只允許一個線程對共享資源進行訪問,如果有多個線程試圖訪問公共資源,那麼在有一個線程進入後,其他試圖訪問公共資源的線程將被掛起,並一直等到進入臨界區的線程離開,臨界區在被釋放後,其他線程纔可以搶佔。
  2. 互斥量:採用互斥對象機制。 只有擁有互斥對象的線程纔有訪問公共資源的權限,因爲互斥對象只有一個,所以能保證公共資源不會同時被多個線程訪問。互斥不僅能實現同一應用程序的公共資源安全共享,還能實現不同應用程序的公共資源安全共享 .互斥量比臨界區複雜。因爲使用互斥不僅僅能夠在同一應用程序不同線程中實現資源的安全共享,而且可以在不同應用程序的線程之間實現對資源的安全共享。
  3. 事 件: 通過通知操作的方式來保持線程的同步,還可以方便實現對多個線程的優先級比較的操作 。
  4. 信號量:它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數目 .信號量對象對線程的同步方式與前面幾種方法不同,信號允許多個線程同時使用共享資源,這與操作系統中的PV操作相同。它指出了同時訪問共享資源的線程最大數目。它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數目

信號量S是一個整數,S大於等於零時代表可供併發進程使用的資源實體數,但S小於零時則表示正在等待使用共享資源的進程數。

P操作申請資源:

  1. S減1;
  2. 若S減1後仍大於等於零,則進程繼續執行;
  3. 若S減1後小於零,則該進程被阻塞後進入與該信號相對應的隊列中,然後轉入進程調度。

V操作 釋放資源:

  1. S加1;
  2. 若相加結果大於零,則進程繼續執行;
  3. 若相加結果小於等於零,則從該信號的等待隊列中喚醒一個等待進程,然後再返回原進程繼續執行或轉入進程調度。

總結:

 

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

  • 什麼是死鎖:多個進程循環等待它方佔有的資源而無限期地僵持下去的局面
  • 產生的必要條件:
  1. 互斥。即某個資源在一段時間內只能由一個進程佔有,不能同時被兩個或兩個以上的進程佔有。
  2. 不可搶佔。進程所獲得的資源在未使用完畢之前,資源申請者不能強行地從資源佔有者手中奪取資源,而只能由該資源的佔有者進程自行釋放。
  3. 佔有且等待。當一個進程等待其他進程時,繼續佔有已分配的資源。
  4. 循環等待。存在一個閉合的進程鏈,每個進程至少佔有此鏈中下一個進程所需的一個資源。
  • 死鎖的預防(死鎖預防的靜態策略):只要破壞這四個必要條件中的任意一個條件,死鎖就不會發生。這就爲我們解決死鎖問題提供了可能。一般地,解決死鎖的方法分爲死鎖的預防,避免,檢測與恢復三種(注意:死鎖的檢測與恢復是一個方法)。
  1. 打破互斥。即允許進程同時訪問某些資源。但是,有的資源是不允許被同時訪問的,像打印機等等,這是由資源本身的屬性所決定的。所以,這種辦法並無實用價值。
  2. 打破不可搶佔。即允許進程強行從佔有者那裏奪取某些資源。就是說,當一個進程已佔有了某些資源,它又申請新的資源,但不能立即被滿足時,它必須釋放所佔有的全部資源,以後再重新申請。它所釋放的資源可以分配給其它進程。這就相當於該進程佔有的資源被隱蔽地強佔了。這種預防死鎖的方法實現起來困難,會降低系統性能。    
  3. 打破佔有且等待。可以實行資源預先分配策略。即進程在運行前一次性地向系統申請它所需要的全部資源。如果某個進程所需的全部資源得不到滿足,則不分配任何資源,此進程暫不運行。只有當系統能夠滿足當前進程的全部資源需求時,才一次性地將所申請的資源全部分配給該進程。由於運行的進程已佔有了它所需的全部資源,所以不會發生佔有資源又申請資源的現象,因此不會發生死鎖。但是,這種策略也有如下缺點:1、在許多情況下,一個進程在執行之前不可能知道它所需要的全部資源。這是由於進程在執行時是動態的,不可預測的;2、資源利用率低。無論所分資源何時用到,一個進程只有在佔有所需的全部資源後才能執行。即使有些資源最後才被該進程用到一次,但該進程在生存期間卻一直佔有它們,造成長期佔着不用的狀況。這顯然是一種極大的資源浪費;3、降低了進程的併發性。因爲資源有限,又加上存在浪費,能分配到所需全部資源的進程個數就必然少了。  
  4. 打破循環等待。實行資源有序分配策略。採用這種策略,即把資源事先分類編號,按號分配,使進程在申請,佔用資源時不會形成環路。所有進程對資源的請求必須嚴格按資源序號遞增的順序提出。進程佔用了小號資源,才能申請大號資源,就不會產生環路,從而預防了死鎖。這種策略與前面的策略相比,資源的利用率和系統吞吐量都有很大提高,但是也存在以下缺點:1、限制了進程對資源的請求,同時給系統中所有資源合理編號也是件困難事,並增加了系統開銷;2、爲了遵循按編號申請的次序,暫不使用的資源也需要提前申請,從而增加了進程對資源的佔用時間。
  • 死鎖避免(死鎖預防的動態策略):它不限制進程有關申請資源的命令,而是對進程所發出的每一個申請資源命令加以動態地檢查,並根據檢查結果決定是否進行資源分配。即在資源分配過程中若預測有發生死鎖的可能性,則加以避免。這種方法的關鍵是確定資源分配的安全性。常見:銀行家算法。
  • 死鎖檢測:由於操作系統有併發,共享以及隨機性等特點,通過預防和避免的手段達到排除死鎖的目的是很困難的。這需要較大的系統開銷,而且不能充分利用資源。爲此,一種簡便的方法是系統爲進程分配資源時,不採取任何限制性措施,但是提供了檢測和解脫死鎖的手段:能發現死鎖並從死鎖狀態中恢復出來。因此,在實際的操作系統中往往採用死鎖的檢測與恢復方法來排除死鎖。死鎖檢測與恢復是指系統設有專門的機構,當死鎖發生時,該機構能夠檢測到死鎖發生的位置和原因,並能通過外力破壞死鎖發生的必要條件,從而使得併發進程從死鎖狀態中恢復出來。
  • 死鎖恢復:檢測到死鎖後需要進行恢復。常用方法:
  1. 最常用的方法就是進行系統的重新啓動,不過這種方法代價很大,它意味着在這之前所有的進程已經完成的計算工作都將付之東流,包括參與死鎖的那些進程,以及未參與死鎖的進程。例如看門狗。
  2. 撤消進程,剝奪資源。終止參與死鎖的進程,收回它們佔有的資源,從而解除死鎖。這時又分兩種情況:一次性撤消參與死鎖的全部進程,剝奪全部資源();或者逐步撤消參與死鎖的進程,逐步收回死鎖進程佔有的資源。一般來說,選擇逐步撤消的進程時要按照一定的原則進行,目的是撤消那些代價最小的進程,比如按進程的優先級確定進程的代價;考慮進程運行時的代價和與此進程相關的外部作業的代價等因素。 
  3. 進程回退策略,即讓參與死鎖的進程回退到沒有發生死鎖前某一點處,並由此點處繼續執行,以求再次執行時不再發生死鎖。雖然這是個較理想的辦法,但是操作起來系統開銷極大,要有堆棧這樣的機構記錄進程的每一步變化,以便今後的回退,有時這是無法做到的。

 

 

 

 

 

 

 

 

 

 

 

 

 

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