目錄
-
-
- 1.程序的互斥
-
- 1.1臨界資源和臨界區
- 1.2遵循準則
- 1.3使用硬體實作互斥
- 1.4信号量實作互斥
- 2.程序的同步
-
- 2.1生産者\消費者問題
- 2.2讀者\寫者問題
- 3.程序之間的通信
-
- 3.1共享記憶體方式
- 3.2管道通信機制
- 3.3消息傳遞機制
- 4.管程
- 5.思維導圖
-
1.程序的互斥
程序互斥是程序同步控制中的一種特例。
1.1臨界資源和臨界區
臨界資源
:某段時間内隻允許一個程序使用的資源。
臨界區
:使用臨街資源的那一部分程式。
1.2遵循準則
為了提供對互斥的支援,系統必須滿足以下條件:
(1)空閑讓進:某程序退出臨界區,剛好有其他程序等待進入臨界區,那麼就讓它進入。
(2)忙則等待:有程序在臨界區中,其他程序必須進行等待。
(3)有限等待:不能讓一個程序在臨界區中無限運作,在有限時間内讓它退出。
(4)讓權等待:如果有優先級更高的程序在等待區中,那麼就讓臨界區的程序讓位。
1.3使用硬體實作互斥
中斷禁用
:保證程序進入臨界區後不被打斷,有效的實作互斥。
while(true)
{
/*禁用中斷*/
臨界區
/*啟用中斷*/
}
缺點:
(1)代價太高,會降低執行效率
(2)不能用于多核處理器結構
專用機器指令
:compare_and_swap 指令
優點:
(1)适用範圍廣
(2)使用簡單
(3)可支援多個臨界區
缺點:
(1)導緻CPU空耗,當一個程序等待進入臨界區時,會不斷地持續檢測
(2)導緻饑餓程序,都有多個程序都等待進入臨界區是,在某些極端情況下可能會導緻某個程序永遠無法進入臨界區。
1.4信号量實作互斥
信号量是一個資料結構,簡寫為s。主要有兩個原語操作wait和signal。
原語wait(s)
:用于申請一個資源,有時候寫為P
void wait(semaphore s)
{
//申請時,資源數減一,如果此時資源數小于0,說明無空閑資源,那麼将程序阻塞,并将其放入等待隊列
s.value=s.value-1;
if(s.value<0)
block(s.queue);
}
原語signal(s)
:用于釋放一個資源,有時候寫為V
void signal(semaphore s)
{
//将資源數加一,如果此時資源數小于等于0,那麼将程序喚醒,并将其放入就緒隊列
s.value=s.value+1;
if(s.value<=0)
wakeup(s.queue);
}
信号量的實體含義
:在使用時對信号量進行初始化,注意初始值應該大于等于0。
在使用wait和signal原語時需要注意使用順序,否則可能會出現死鎖。
2.程序的同步
在使用信号量實作程序同步時,一個信号量需要和一個消息對應起來。
2.1生産者\消費者問題
問題描述
:生産者生産産品放入緩沖區中,當緩沖區滿時則發生阻塞。消費者從緩沖區中取出産品,當緩沖區為空時,則發生阻塞。
解決方案
:這裡我們設定三個信号量,S1、mutex、S2,分别表示緩沖區是否還有空位、該時刻隻可以進行一個操作(生産或者消費)、緩沖區是否已滿;定義兩個變量i和j分别指向生産産品的位置和消費産品的位置。
2.2讀者\寫者問題
問題描述
:讀者和寫者共享一組資料區,允許多個讀者同時執行讀操作,不允許讀者、寫者同時操作,不允許多個寫者同時操做。
解決方案
:假設讀優先,即有寫着等待,但是有其他讀者讀,那麼新讀者也可以進行讀操作。設定信号量w用于讀者和寫者、寫者和寫者之間的互斥;設定信号量readcount表示正在讀的讀者個數;設定mutex來對readcount這個臨界資源的互斥通路。
3.程序之間的通信
程序之間根據通信内容可以分為
控制資訊的傳送
和
大批量資料的傳送
;根據進階通信機制可以分為:
共享記憶體方式
、
管道通信機制
、
消息傳遞機制
。
3.1共享記憶體方式
使用共享記憶體可以避免對一個内容的反複通路,但是要注意實作存儲區通路的互斥。
3.2管道通信機制
管道通信用于連接配接一個讀程序和一個寫程序,實作程序之間通信的一種共享檔案,又稱為pipe檔案。
以字元流形式将大量資料送入管道,它可以傳送大量資料,是以被廣泛采用。
3.3消息傳遞機制
以資訊為機關,可以分為直接通信方式和間接通信方式。
直接通信方式
:發送程序直接将消息發給接受程序,接受程序可以接受任意發送發的消息,并且知道發送方是誰。
簡介通信方式
:消息并不直接送達,而是發送到臨時消息隊列(信箱)。具有很大的靈活性,可以一對一、一對多、多對多、多對一。
4.管程
把分散在各程序中的臨界區集中起來進行管理,防止程序有意或者無意的違法同步操作。