作業系統讀書筆記(5)

2021-07-15 10:53:09 字數 4531 閱讀 6125

這部分主要是複習併發:死鎖和飢餓

1、可重用資源  可消耗資源

可重用資源是指一次只能供乙個程序安全地使用,並且不會由於使用而耗盡的資源。程序得到資源,後來又釋放這些資源單元,供其他程序再次使用。可重用資源例子包括:處理器、i/o通道、記憶體和外存、裝置以及諸如檔案、資料庫和訊號量之類的資料結構。

可消耗資源是指可以被建立(生產)和銷毀(消耗)的資源。當消費程序得到乙個資源時,該資源就不再存在了。可消耗資源的例子有中斷、訊號、訊息和i/o緩衝區中的資訊。

2、死鎖的必要條件

互斥:一次只有乙個程序可以使用乙個資源,其他程序不能訪問已經分配給其他程序的資源

占有且等待:當乙個程序在等待其他程序時,繼續占有已經分配的資源

不可搶占:不能強行搶占程序已占有的資源

有三種方法可以處理死鎖。第一種方法是採用某種策略來消除上述四個條件中的乙個條件的出現來預防死鎖;第二種方法是基於資源分配的當前狀態做動態的選擇來避免死鎖;第三種方法是試圖檢測死鎖(滿足1至4)的存在並且試圖從死鎖中恢復出來。  

死鎖預防

簡單講,死鎖預防策略是試圖設計一種系統來排除發生死鎖的可能性。方法分為兩大類:一種是間接的死鎖預防方法,即防止前面列出的三個必要條件中的任何乙個發生;一種是直接的死鎖預防方法,即防止迴圈等待的發生。

死鎖避免

在死鎖預防中,通過約束資源請求,防止4個條件中至少乙個的發生,可以通過直接或間接預防方法,但是這都會導致低效的資源使用和低效的程序執行。

死鎖避免則相反,它允許前三個必要條件,但是通過明智的選擇,確保永遠不會到達死鎖點,因此死鎖避免比死鎖預防允許更多的併發。在死鎖避免中,是否允許當前資源分配請求是通過判斷該請求是否可能導致死鎖來決定的。因此,死鎖避免需要知道將來的程序資源請求的情況。

死鎖避免策略並不能確切的**死鎖,它僅僅是**死鎖的可能性並確保永遠不會出現這種可能性。

有兩種死鎖避免的辦法:

死鎖檢測

死鎖預防策略是非常保守的,他們通過限制訪問資源和在程序上強加約束來解決死鎖的問題。死鎖檢測則是完全相反,

它不限制資源訪問或約束程序行為,只要有可能,被請求的資源就被授權給程序。

作業系統周期性地執行乙個演算法檢測前面的迴圈等待的條件。

3、一種綜合的死鎖策略

所有的解決死鎖的策略都有其優缺點,在不同的情況下使用不同的策略比將作業系統機制設計為只採用其中一種策略更有效。

作為這種技術的乙個例子,考慮下列資源類:

4、哲學家就餐問題

哲學家就餐問題可以看做是應用程式中包含併發執行緒的執行時,協調處理共享資源的乙個代表性問題。

哲學家就餐問題描述:5個哲學家,5個筷子。5個哲學家圍坐在一張桌子上,筷子放在分別放在每個哲學家的兩旁。如果所有哲學家在某個時刻同時拿起左邊的筷子,那麼右邊的筷子就都被其他的哲學家拿了,造成大家都無法吃飯。但是大家都不想放下左邊的筷子(規則是先拿起左邊筷子在拿起右邊的,吃完飯在放下兩個筷子),這就是死鎖。

解決這個問題有個辦法是在拿起筷子前先判斷左右兩個筷子是否可用,可用才能拿,而且是同時拿,這樣不相鄰的哲學家就可以吃上飯,不會造成死鎖。

(1)使用訊號量解決

考慮增加一位服務員,他只允許4位哲學家同時進入餐廳,因此至少有一位哲學家可以同時拿到2把叉子。這個方案不會發生死鎖和飢餓。

semaphore fork[5]=;

semaphore room=;

int i;

void philosoper(int i)

}void main()

(2)使用管程解決

和訊號量不同的是,管程不會發生死鎖,因為在同一時刻只有乙個程序進入管程。使用管程的方案定義了乙個含有5個條件變數的向量,每把叉子對應乙個條件變數。這些條件變數用來標識哲學家等待的叉子的可用情況,每乙個布林向量記錄每把叉子的使用狀態(true標識叉子可用)。

monitor dining_controller;

cond forkready[5];

boolean fork[5]=;

void get_forks(int pid)

void release_forks(int pid)

void philosoper[k=0 to 4]

}

5、unix的併發機制

unix為程序間的通訊和同步提供了各種機制。管道、訊息和共享記憶體提供了程序間傳遞資料的方法,而訊號量和訊號則用於其他程序的觸發行為。

(1)管道:管道是乙個環形緩衝區,允許兩個程序以生產者、消費者的模式進行通訊,這是乙個先進先出佇列,由乙個程序寫,而另乙個程序讀。

管道在建立的時候獲得乙個固定大小的位元組數。當乙個程序試圖往管道中寫時,要有足夠的空間寫請求才能被立即執行,否則該程序會被阻塞。類似的讀程序也是這樣。作業系統強制實施互斥,即一次只能有乙個程序訪問管道。

(2)訊息:訊息是有型別的一段文字。unix系統為參與訊息傳遞的程序提供msgsnd和msgrcv系統呼叫。每個程序都有乙個與之關聯的訊息佇列,其功能類似於信箱。

訊息傳送者指定傳送的每個訊息的型別,型別可以被訊息接收者用作選擇的依據。接收者可以按先進先出的順序接收,或者按型別接收。

(3)共享記憶體:共享記憶體是unix提供的程序間通訊手段中速度最快的一種。這是虛存中由多個程序共享的乙個公共記憶體塊。每乙個程序有乙個唯讀或只寫的許可權。互斥約束不屬於共享記憶體機制的一部分,但必須由使用共享記憶體的程序提供。

(4)訊號量:訊號量(semaphore)是乙個計數器,用於多程序對共享資料的訪問

為了獲得共享資源,程序需要執行下列操作:

a. 測試控制資源的訊號量。

b. 若此訊號量的值為正,則程序可以使用該資源。程序將訊號量值減1,表示它使用了乙個資源單位。

c. 若此訊號量的值為0,則程序進入休眠狀態,直至訊號量值大於0。程序被喚醒後,它返回執行第a步。

當程序不再使用此共享資源時,該訊號量值增1。(返還乙個資源單位) 如果有程序正在休眠等待此訊號量,則喚醒它們。

為了正確地實現訊號量,訊號量值的測試及減1操作應當是原子操作。為此,訊號量通常是在核心中實現的。

(5)訊號:訊號是用於向乙個程序通知發生非同步事件的機制。訊號類似於硬體中斷,但沒有優先順序,即核心平等的對待所有訊號。對於同時發生的訊號,一次只給程序乙個訊號,而沒有特定的次序。

6、linux核心併發機制

linux包含了在其他unix系統中出現的所有併發機制,其中包括管道、訊息、共享記憶體和訊號。除此之外,linux還包含了特別為核心態執行緒準備的併發機制。換言之,他們是用在核心中的併發機制,為核心**提供執行時的併發性。

(1)原子操作

原子操作在執行時不會被打斷或者干涉。在單處理器中,一旦啟動原子操作,從開始到結束的時間內,執行緒不能被中斷。在多處理器系統中,原子操作所針對的變數是鎖住的,以免被其他程序所訪問,知道原子操作的結束。

(2)自旋鎖

在linux中保護臨界區最常見的技術是自旋鎖。在同一時刻,只有乙個執行緒能獲得自旋鎖。其他企圖獲得自旋鎖的任何執行緒將一直進行嘗試(即自旋),直到獲得了該鎖。

本質上,自旋鎖建立在記憶體區中的乙個整數上,任何執行緒在進去臨界區之前都必須檢查該整數。如果該值為0,則執行緒設定它為1,然後進入臨界區。如果該值非0,則執行緒繼續檢查該值。自旋鎖很容易實現,但是缺點是在鎖外面的執行緒以忙等待的方式繼續進行。

讀寫自旋鎖機制允許在核心中實現比基本自旋鎖更高的併發度。讀寫自旋鎖允許多個執行緒同時以唯讀的方式訪問同乙個資料結構,只有當乙個執行緒想要更新資料結構時,才會互斥地訪問該自旋鎖。相對於寫者而言,讀寫自旋鎖對讀者更有利,如果自旋鎖被讀者擁有,那麼寫者就不能搶占該鎖,新來的讀者比已經等待的寫者會搶先獲得該自旋鎖。

(3)訊號量

在使用者層上,linux提供了和unix對應的訊號量介面。在核心內部,linux提供了供自己使用的訊號量具體實現,即在核心中的**中能夠呼叫核心訊號量。核心訊號量比使用者可見的通過系統呼叫被使用者程式訪問的訊號量更加高效。

linux在核心中提供了三種訊號量:二元訊號量(也叫互斥訊號量)、計數訊號量、讀寫訊號量(實際上對於讀者使用的是乙個計數訊號量,對寫者使用的是乙個二元訊號量)。

(4)屏障

在一些體系中,編譯器或者處理器為了優化效能,可能會對源**中的記憶體訪問重新排序。重新排序是為了優化對處理器指令流水線的使用。但是在某些情況下,讀操作和寫操作以指定的順序執行是相當重要的。為了保證指令執行的順序,linux提供了記憶體屏障設施。

比如在rmb()操作保證了**中在rmb()以前的**沒有任何讀操作會穿過屏障;相似的,wmb()操作保證了在**wmb()以前的**沒有任何寫操作會穿過屏障;mb()操作提供了裝載和儲存屏障。

作業系統讀書筆記

前言管程 訊號量體系有內容如下 整型訊號量 記錄型訊號量 and型訊號量 訊號量集。最容易搞混的就是整型訊號量和記錄型訊號量,理解之後很容易區分,記住一點 整型訊號量不遵循 讓權等待 的原則,只要待操作的訊號量s 0,就會處於一種 忙等待 的狀態,更嚴重的是,一旦事件發生,會導致一種稱之為 驚群現象...

作業系統讀書筆記1

最近在看 現代作業系統 這本書,希望在break期間把重要的幾章看完,同時做些筆記。第一章基本上是對作業系統總體的介紹,各方面都涉及到。花了我乙個下午和乙個晚上才讀完。有幾點印象比較深 1 作業系統兩個作用 一是提供抽象,便於在上層設計各種程式 而是合理的有效的管理資源。2 cache是個重要的理念...

讀書筆記 現代作業系統

ch1.1.作業系統中,抽象非常重要,乙個複雜的任務可以抽象成多個簡單的子任務,將複雜的硬體抽象成簡單的介面,書中針對向上層應用提供的介面做詳細的講解,但是對於使用者 終端使用者 介面不會做研究.2.作業系統中的資源有時間資源和空間資源,以及硬碟的空間資源,時間資源是時間復用的 如cpu的輪轉 空間...