操作系統——進程和線程相關面試常見題

1、進程和線程有什麼區別?

1、進程(Process)是系統進行資源分配和調度的基本單位,線程(Thread)是CPU調度和分派的基本單位;

2、線程依賴於進程而存在,一個進程至少有一個線程;

3、進程有自己的獨立地址空間,線程共享所屬進程的地址空間;

4、進程是擁有系統資源的一個獨立單位,而線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧),和其他線程共享本進程的相關資源如內存、I/O、cpu等;

5、在進程切換時,涉及到整個當前進程CPU環境的保存環境的設置以及新被調度運行的CPU環境的設置,而線程切換隻需保存和設置少量的寄存器的內容,並不涉及存儲器管理方面的操作,可見,進程切換的開銷遠大於線程切換的開銷;

6、線程之間的通信更方便,同一進程下的線程共享全局變量等數據,而進程之間的通信需要以進程間通信(IPC)的方式進行;

7、多線程程序只要有一個線程崩潰,整個程序就崩潰了,但多進程程序中一個進程崩潰並不會對其它進程造成影響,因爲進程有自己的獨立地址空間,因此多進程更加健壯

2、進程間通信有哪些方式?

1、管道

管道(Pipe)- 管道是半雙工的,數據只能向一個方向流動;需要雙方通信時,需要建立起兩個管道;

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

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

特點:
1、面向字節流,
2、生命週期隨內核
3、自帶同步互斥機制。
4、半雙工,單向通信,兩個管道實現雙向通信。

2、 消息隊列

在內核中創建一隊列,隊列中每個元素是一個數據報,不同的進程可以通過句柄去訪問這個隊列。消息隊列提供了⼀個從⼀個進程向另外⼀個進程發送⼀塊數據的⽅法。
每個消息隊 列的總的字節數是有上限的(MSGMNB),系統上消息隊列的總數也有⼀個上限(MSGMNI)

特點:
1、消息隊列允許一個或多個進程寫入或者讀取消息。
2、消息隊列的生命週期隨內核。
3、消息隊列可實現雙向通信。

3、信號量

信號量的本質是一種數據操作鎖,用來負責數據操作過程中的互斥,同步等功能。

信號和信號量是不同的,它們雖然都可以用來同步和互斥,但是信號是使用信號處理器來進行的,信號量是使用P,V操作來實現的。

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

功能:
對臨界資源進行保護。

4、共享內存
在這裏插入圖片描述

將同一塊物理內存一塊映射到不同的進程的虛擬地址空間中,實現不同進程間對同一資源的共享。共享內存可以說是最有用的進程間通信方式,也是最快的IPC形式。

特點:
1、不用從用戶態到內核態的頻繁切換和拷貝數據,直接從內存中讀取就可以。
2、共享內存是臨界資源,所以需要操作時必須要保證原子性。使用信號量或者互斥鎖都可以。
3、生命週期隨內核。

5、 套接字(Socket)

可用於不同機器間的進程通信。

例如我們平時通過瀏覽器發起一個 http 請求,然後服務器給你返回對應的數據,這種就是採用 Socket 的通信方式了。

3、進程同步問題

進程間同步的主要方法有原子操作信號量機制自旋鎖管程會合分佈式系統等。

4、線程有幾種狀態,進程呢?

1、線程

線程從最初的創建到最終的消亡,要經歷若干個狀態:創建(new)就緒(runnable/start)運行(running)阻塞(blocked)等待(waiting)時間等待(time waiting)消亡(dead/terminated)。在給定的時間點上,一個線程只能處於一種狀態。

2、進程

1、就緒狀態:已具備運行條件,但是由於沒有閒置CPU,暫時不能運行。

2、運行狀態:佔有CPU,並在CPU上運行。

3、阻塞狀態:因等待某一事件而暫時不能運行。

在這裏插入圖片描述

在這裏插入圖片描述

5、進程調度策略有哪些?

FCFS(先來先服務)優先級,時間片輪轉,多級反饋

1、FCFS(先來先服務,隊列實現,非搶佔的):先請求CPU的進程先分配到CPU

2、SJF(最短作業優先調度算法):平均等待時間最短,但難以知道下一個CPU區間長度

3、優先級調度算法(可以是搶佔的,也可以是非搶佔的):優先級越高越先分配到CPU,相同優先級先到先服務,存在的主要問題是:低優先級進程無窮等待CPU,會導致無窮阻塞或飢餓;解決方案:老化

4、時間片輪轉調度算法(可搶佔的):隊列中沒有進程被分配超過一個時間片的CPU時間,除非它是唯一可運行的進程。如果進程的CPU區間超過了一個時間片,那麼該進程就被搶佔並放回就緒隊列。

5、多級隊列調度算法:將就緒隊列分成多個獨立的隊列,每個隊列都有自己的調度算法,隊列之間採用固定優先級搶佔調度。其中,一個進程根據自身屬性被永久地分配到一個隊列中。

6、多級反饋隊列調度算法:與多級隊列調度算法相比,其允許進程在隊列之間移動:若進程使用過多CPU時間,那麼它會被轉移到更低的優先級隊列;在較低優先級隊列等待時間過長的進程會被轉移到更高優先級隊列,以防止飢餓發生。

6、什麼是殭屍進程?

7、線程同步有哪些方式?

爲什麼需要線程同步
線程有時候會和其他線程共享一些資源,比如內存、數據庫等。當多個線程同時讀寫同一份共享資源的時候,可能會發生衝突。因此需要線程的同步,多個線程按順序訪問資源。

互斥量 Mutex

互斥量是內核對象,只有擁有互斥對象的線程纔有訪問互斥資源的權限。因爲互斥對象只有一個,所以可以保證互斥資源不會被多個線程同時訪問;當前擁有互斥對象的線程處理完任務後必須將互斥對象交出,以便其他線程訪問該資源;

信號量 Semaphore

信號量是內核對象,它允許同一時刻多個線程訪問同一資源,但是需要控制同一時刻訪問此資源的最大線程數量。信號量對象保存了最大資源計數當前可用資源計數,每增加一個線程對共享資源的訪問,當前可用資源計數就減1,只要當前可用資源計數大於0,就可以發出信號量信號,如果爲0,則將線程放入一個隊列中等待。線程處理完共享資源後,應在離開的同時通過ReleaseSemaphore函數將當前可用資源數加1。如果信號量的取值只能爲0或1,那麼信號量就成爲了互斥量;

事件 Event

允許一個線程在處理完一個任務後,主動喚醒另外一個線程執行任務。事件分爲手動重置事件和自動重置事件。手動重置事件被設置爲激發狀態後,會喚醒所有等待的線程,而且一直保持爲激發狀態,直到程序重新把它設置爲未激發狀態。自動重置事件被設置爲激發狀態後,會喚醒一個等待中的線程,然後自動恢復爲未激發狀態。

臨界區 Critical Section

任意時刻只允許一個線程對臨界資源進行訪問。擁有臨界區對象的線程可以訪問該臨界資源,其它試圖訪問該資源的線程將被掛起,直到臨界區對象被釋放。

8、什麼是協程?

協程是一種用戶態的輕量級線程,協程的調度完全由用戶控制。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧,直接操作棧則基本沒有內核切換的開銷,可以不加鎖的訪問全局變量,所以上下文的切換非常快。

協程多與線程進行比較?

1. 一個線程可以擁有多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。

2. 線程進程都是同步機制,而協程則是異步

3. 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態

9、什麼是IO多路複用?怎麼實現?

10、什麼是用戶態和內核態?

在計算機系統中,通常運行着兩類程序:系統程序和應用程序,爲了保證系統程序不被應用程序有意或無意地破壞,爲計算機設置了兩種狀態:

系統態(也稱爲管態或核心態),操作系統在系統態運行——運行操作系統程序

用戶態(也稱爲目態),應用程序只能在用戶態運行——運行用戶程序
在實際運行過程中,處理機會在系統態和用戶態間切換。

現代多數操作系統將 CPU 的指令集分爲特權指令和非特權指令兩類:

1) 特權指令——在系統態時運行的指令

對內存空間的訪問範圍基本不受限制,不僅能訪問用戶存儲空間,也能訪問系統存儲空間,特權指令只允許操作系統使用,不允許應用程序使用,否則會引起系統混亂。

2) 非特權指令——在用戶態時運行的指令

一般應用程序所使用的都是非特權指令,它只能完成一般性的操作和任務,不能對系統中的硬件和軟件直接進行訪問,其對內存的訪問範圍也侷限於用戶空間。

用戶態切換到內核態的唯一途徑——>中斷/異常/陷入
內核態切換到用戶態的途徑——>設置程序狀態字

11、孤兒進程,殭屍進程,守護進程

1、孤兒進程

如果父進程先退出,子進程還沒退出那麼子進程將被託孤給init進程,這是子進程的父進程就是init進程(1號進程).其實還是很好理解的。

2、殭屍進程

如果我們瞭解過linux進程狀態及轉換關係,我們應該知道進程這麼多狀態中有一種狀態是僵死狀態,就是進程終止後進入僵死狀態(zombie),等待告知父進程自己終止,後才能完全消失.但是如果一個進程已經終止了,但是其父進程還沒有獲取其狀態,那麼這個進程就稱之爲殭屍進程.殭屍進程還會消耗一定的系統資源,並且還保留一些概要信息供父進程查詢子進程的狀態可以提供父進程想要的信息.一旦父進程得到想要的信息,殭屍進程就會結束。

3、守護進程

同樣我們需要了解一下什麼是守護進程,守護進程就是在後臺運行,不與任何終端關聯的進程,通常情況下守護進程在系統啓動時就在運行,它們以root用戶或者其他特殊用戶(apache和postfix)運行,並能處理一些系統級的任務.習慣上守護進程的名字通常以d結尾(sshd),但這些不是必須的。

12、線程池

多線程的異步執行方式,雖然能夠最大限度發揮多核計算機的計算能力,但是如果不加控制,反而會對系統造成負擔。線程本身也要佔用內存空間,大量的線程會佔用內存資源並且可能會導致Out of Memory。即便沒有這樣的情況,大量的線程回收也會給GC帶來很大的壓力。

爲了避免重複的創建線程,線程池的出現可以讓線程進行復用。通俗點講,當有工作來,就會向線程池拿一個線程,當工作完成後,並不是直接關閉線程,而是將這個線程歸還給線程池供其他任務使用。

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