操作系統 200312

1. 什麼是殭屍進程?什麼是孤兒進程?有什麼危害?

殭屍進程:

  • 一個進程使用 fork 創建子進程,如果子進程退出,而父進程並沒有調用 wait 或者 waitpid 獲取子進程的狀態信息,那麼子進程的進程描述符等一系列信息還會保存在系統中。這種進程稱之爲殭屍進程。

  • “殭屍” 進程是一個早已死亡的進程,但在進程表(processs table)中仍佔了一個位置(slot)。由於進程表的容量是有限的,所以,defunct 進程不僅佔用系統的內存資源,影響系統的性能,而且如果其數目太多,還會導致系統癱瘓。

處理殭屍進程:

  • 改寫父進程,在子進程死後要爲它收屍。具體做法是接管 SIGCHLD 信號。子進程死後,會發送 SIGCHLD 信號給父進程,父進程收到此信號後,執行 waitpid () 函數爲子進程收屍。這是基於這樣的原理:就算父進程沒有調用 wait,內核也會向它發送 SIGCHLD 消息,儘管默認處理是忽略,如果想響應這個消息,可以設置一個處理函數。
  • 把父進程殺掉。父進程死後,殭屍進程成爲” 孤兒進程”,過繼給 1 號進程 init,init 始終會負責清理殭屍進程.它產生的所有殭屍進程也跟着消失。

孤兒進程:

  • 父進程運行結束,但子進程還在運行 (未運行結束) 的子進程就稱爲孤兒進程。

  • 孤兒進程最終會被 init 進程 (進程號爲 1) 所收養,因此 init 進程此時變成孤兒進程的父進程,並由 init 進程對它們完成狀態收集工作。


2. CPU的上下文切換有幾種?系統中斷進行了幾次上下文切換?

上下文切換 (Context Switch) 是一種將 CPU 資源從一個進程分配給另一個進程的機制。操作系統需要先存儲當前進程的狀態 (包括內存空間的指針,當前執行完的指令等等),再讀入下一個進程的狀態,然後執行此進程。

CPU 的上下文切換分三種:進程上下文切換、線程上下文切換、中斷上下文切換

系統調用過程中也會發生 CPU 上下文切換。CPU 寄存器會先保存用戶態的狀態,然後加載內核態相關內容。系統調用結束之後,CPU 寄存器要恢復原來保存的用戶態,繼續運行進程。所以,一次系統調用,發生兩次 CPU 上下文切換

進程是由內核管理和調度的,進程的切換隻能發生在內核態。進程上下文切換與系統調用的不同在於,進程的調用會保存用戶空間的虛擬內存,全局變量等信息,但是系統調用的上下文則不會,因爲其未發生進程的變化。

內核中的任務調度實際是在調度線程,進程只是給線程提供虛擬內存、全局變量等資源。線程上下文切換時,共享相同的虛擬內存和全局變量等資源不需要修改。而線程自己的私有數據,如棧和寄存器等,上下文切換時需要保存。


3. 進程的通信方式?效率最高的通信方式是什麼?

  • 管道:管道是單向的、先進先出的、無結構的、固定大小的字節流,它把一個進程的標準輸出和另一個進程的標準輸入連接在一起。寫進程在管道的尾端寫入數據,讀進程在管道的道端讀出數據。數據讀出後將從管道中移走,其它讀進程都不能再讀到這些數據。管道提供了簡單的流控制機制。進程試圖讀空管道時,在有數據寫入管道前,進程將一直阻塞。同樣地,管道已經滿時,進程再試圖寫管道,在其它進程從管道中移走數據之前,寫進程將一直阻塞。

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

  • 消息隊列:是一個在系統內核中用來保存消息的隊列,它在系統內核中是以消息鏈表的形式出現的。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。

  • 共享內存:共享內存允許兩個或多個進程訪問同一個邏輯內存。這一段內存可以被兩個或兩個以上的進程映射至自身的地址空間中,一個進程寫入共享內存的信息,可以被其他使用這個共享內存的進程,通過一個簡單的內存讀取讀出,從而實現了進程間的通信。如果某個進程向共享內存寫入數據,所做的改動將立即影響到可以訪問同一段共享內存的任何其他進程。共享內存是最快的 IPC 方式,它是針對其它進程間通信方式運行效率低而專門設計的。它往往與其它通信機制(如信號量)配合使用,來實現進程間的同步和通信。

  • 套接字:套接字也是一種進程間通信機制,與其它通信機制不同的是,它可用於不同機器間的進程通信。


4. 進程調度算法有幾種?應用最廣泛的是什麼?

批處理任務:

  • 先來先服務 (FCFS)

  • 短作業優先(SJF)

  • 最短剩餘時間優先(SRTN)

  • 優先權調度

交互式任務:

  • 時間片輪轉

  • 多級調度隊列

  • 多級反饋隊列

FIFO 或 First Come, First Served (FCFS) 先來先服務

  • 調度的順序就是任務到達就緒隊列的順序。

  • 公平、簡單 (FIFO 隊列)、非搶佔、不適合交互式。

  • 未考慮任務特性,平均等待時間可以縮短。

Shortest Job First (SJF) 最短作業優先

  • 最短的作業 (CPU 區間長度最小) 最先調度。

  • 由於作業的長短只是根據用戶所提供的估計執行時間而定的,而用戶又可能會有意或無意地縮短其作業的估計運行時間,致使該算法不一定能真正做到短作業優先調度。

  • SJF 可以保證最小的平均等待時間。

Shortest Remaining Job First (SRJF) 最短剩餘作業優先

  • SJF 的可搶佔版本,比 SJF 更有優勢。

  • SJF (SRJF): 如何知道下一 CPU 區間大小?根據歷史進行預測:指數平均法。

優先權調度

  • 每個任務關聯一個優先權,調度優先權最高的任務。

  • 優先權太低的任務一直就緒,得不到運行,出現 “飢餓” 現象。

Round-Robin (RR) 輪轉調度算法

  • 設置一個時間片,按時間片來輪轉調度(“輪叫” 算法)

  • 優點:定時有響應,等待時間較短;

  • 缺點:上下文切換次數較多;

  • 時間片太大,響應時間太長;吞吐量變小,週轉時間變長;當時間片過長時,退化爲 FCFS。

多級隊列調度

  • 按照一定的規則建立多個進程隊列
  • 不同的隊列有固定的優先級(高優先級有搶佔權)
  • 不同的隊列可以給不同的時間片和採用不同的調度方法
  • 存在問題 1:沒法區分 I/O bound 和 CPU bound;
  • 存在問題 2:也存在一定程度的 “飢餓” 現象;

多級反饋隊列

  • 在多級隊列的基礎上,任務可以在隊列之間移動,更細緻的區分任務。
  • 可以根據 “享用” CPU 時間多少來移動隊列,阻止 “飢餓”。
  • 最通用的調度算法,多數 OS 都使用該方法或其變形,如 UNIX、Windows 等。

多級反饋隊列算法詳解:

  • 進程在進入待調度的隊列等待時,首先進入優先級最高的 Q1 等待。
  • 首先調度優先級高的隊列中的進程。若高優先級中隊列中已沒有調度的進程,則調度次優先級隊列中的進程。例如:Q1,Q2,Q3 三個隊列,只有在 Q1 中沒有進程等待時纔去調度 Q2,同理,只有 Q1,Q2 都爲空時纔會去調度 Q3。
  • 對於同一個隊列中的各個進程,按照時間片輪轉法調度。比如 Q1 隊列的時間片爲 N,那麼 Q1 中的作業在經歷了 N 個時間片後若還沒有完成,則進入 Q2 隊列等待,若 Q2 的時間片用完後作業還不能完成,一直進入下一級隊列,直至完成。
  • 在低優先級的隊列中的進程在運行時,又有新到達的作業,那麼在運行完這個時間片後,CPU 馬上分配給新到達的作業(搶佔式)。

5. 進程和線程的區別?

進程是具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。

線程是進程的一個實體,是 CPU 調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。

區別:

  • 進程有自己的獨立地址空間,線程沒有

  • 進程是資源分配的最小單位,線程是 CPU 調度的最小單位。

  • 進程和線程通信方式不同 (線程之間的通信比較方便。同一進程下的線程共享數據,比如全局變量,靜態變量,通過這些數據來通信不僅快捷而且方便,當然如何處理好這些訪問的同步與互斥正是編寫多線程程序的難點。而進程之間的通信只能通過進程通信的方式進行。)

  • 進程上下文切換開銷大,線程開銷小;對進程進程操作一般開銷都比較大,對線程開銷就小了

  • 一個進程掛掉了不會影響其他進程,而線程掛掉了會影響其他線程。


【Java 面試那點事】

這裏致力於分享 Java 面試路上的各種知識,無論是技術還是經驗,你需要的這裏都有!

這裏可以讓你【快速瞭解 Java 相關知識】,並且【短時間在面試方面有跨越式提升】

面試路上,你不孤單!
在這裏插入圖片描述

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