操作系統常問面試題總結(持續更新)

Q1: 進程間的通信方式

1. 匿名管道

管道是通過調用 pipe 函數創建的,fd[0] 用於讀,fd[1] 用於寫

int pipe(int fd[2]);

存在形式:
無名管道:只存在於內存中的文件

使用限制:

  • 只支持半雙工(單向交替傳輸)
  • 只能在父子進程或兄弟進程中使用
    在這裏插入圖片描述

2. 命名管道

解決了匿名管道的只能在父子進程中使用的限制。

存在形式:
命名管道:存在於實際的磁盤介質或者文件系統

#include <sys/stat.h>
int mkfifo(const char *path, mode_t mode);
int mkfifoat(int fd, const char *path, mode_t mode);

FIFO 常用於客戶-服務器應用程序中,FIFO 用作匯聚點,在客戶進程和服務器進程之間傳遞數據。

管道的實現機制:

管道是由內核管理的一個緩衝區,這個緩衝區被設計成爲環形的數據結構,以便管道可以被循環利用。當管道中沒有信息的話,從管道中讀取的進程會等待,直到另一端的進程放入信息。當管道被放滿信息的時候,嘗試放入信息的進程會等待,直到另一端的進程取出信息。

3. 消息隊列

消息隊列是消息的鏈表,具有特定的格式,存放在內存中並由消息隊列標識符標識。 進程控制塊(PCB)中有對應的字段會保存對應消息隊列的標識符.

存在形式:

消息隊列存放在內核中,只有在內核重啓(即,操作系統重啓)或者顯示地刪除一個消息隊列時,該消息隊列纔會被真正的刪除。

消息隊列的優點:

  • 可以對消息隨機讀取,而不是像管道那樣只能FIFO
  • 比起管道, 消息隊列能存儲的信息更多更豐富

4. 信號量

信號量可以理解成一個計數器,用於解決多個進程訪問共享資源時的同步問題。

5. 共享內存

使多個進程可以訪問同一塊內存空間,不同進程可以及時看到對方進程中對共享內存中數據的更新。 這種方式需要依靠某種同步操作,例如:互斥鎖和信號量等。

6. 套接字

此方法主要用於不在同一臺機器上的進程間的通信,例如客戶端的一個進程和服務端的一個進程進行通信。


Q2: 線程間的同步方式有哪些

1. 互斥量(mutex) (搶佔式同步)

就是上鎖,在java中主要就是 synchronized 和 各種Lock.

2. 信號量(Semphore) (非搶佔式同步)

允許多個線程訪問同一個資源,但需要控制同一時刻訪問此資源的最大線程數量

3. Java對管程的實現( wait / notify )

通過wait和notify來實現同步


Q3:死鎖產生的條件

1. 互斥

每一個資源只能分給一個進程.

2. 佔用和等待

已經得到了某個資源的進程可以再請求新的資源. 並且可以在持有一些資源的狀態下去等待暫時無法獲取的資源

3. 不可搶佔

已經分配給一個進程的資源,在這個進程沒有使用完或主動釋放之前,都不能被其他進程獲取.

4. 環路等待

在這裏插入圖片描述


Q4: 解決死鎖的策略:

1. 鴕鳥策略(解決策略就是不去解決)

因爲解決死鎖的代價會比較大,且死鎖發生的概率又比較小,並且死鎖也不會對用戶造成致命影響的話,那麼就忽略它好了…

2. 死鎖檢測與死鎖恢復

不試圖阻止死鎖,而是當檢測到死鎖發生的時候,採取一些措施進行一個恢復

檢測到死鎖後的恢復策略:

  • 利用搶佔恢復
  • 利用回滾恢復
  • 通過殺死進程恢復

其實就是破壞死鎖的必要條件中的一個就行了…

3. 死鎖預防

在程序運行之前就預防發生死鎖,就是破壞死鎖產生的必要條件中的一個就行。

例如:

  • 給資源統一編號,進程只能按編號順序來請求資源,破壞了環路等待;
  • 分配資源時,一次性把所有資源都分配出去, 破壞了佔有並等待;

4. 死鎖避免

在程序運行時,避免發生死鎖。 使用銀行家算法,保證在資源分配後依然能讓系統處於安全狀態… 如果不安全的話就拒絕分配.


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