作業系統 程序通訊

2021-08-31 16:01:49 字數 2666 閱讀 1891

競爭條件

兩個或多個程序讀寫某些共享資料,而最後的結果取決於程序執行的精確時序,稱為競爭條件。凡涉及到資源的共享時就容易發生這樣的事情。解決的辦法是設立臨界區,讓程序互斥地訪問共享資源。乙個好的避免競爭條件的方案,必須滿足4個條件:

任何兩個程序不能同時處於臨界區。

不應對cpu的速度和數量做任何假設。

臨界區外執行的程序不得阻塞其它程序。

不得讓程序無限期等待進入臨界區。

忙等待互斥

1.遮蔽中斷

程序在進入臨界區時遮蔽中斷(包括時鐘中斷),離開臨界區時開啟中斷。這使得cpu無法切換到其它程序。這種方案的缺點在於,將中斷遮蔽的程序可能不再將中斷開啟,導致cpu永遠無法切換程序;而且遮蔽的只是該程序對應的cpu的中斷,其它沒有被遮蔽中斷的cpu仍然可以訪問共享資源。在多核系統中,這種方法並不適用。

2、鎖變數

程序進入臨界區之前必須先持有鎖,然後將鎖占有,其它程序得不到所而在臨界區外等待。但這種方案的缺陷在於,程序在判斷鎖可用到占有鎖之間可能會被排程,另乙個程序同樣發現鎖可用並進入臨界區。這會導致兩個程序同時進入臨界區。

3、嚴格輪換法

程序等待某個變數被置位後才能進入臨界區,如下圖所示:

程序a在turn變為0之前迴圈等待;程序b在turn變為1之前迴圈等待。這屬於忙等待,很顯然浪費了cpu時間。用於忙等待的鎖稱為自旋鎖。這種方案的問題在於,兩個程序必須按照嚴格的順序交替進入臨界區,這會降低速度較快的程序的執行效率。也就是違反了上述條件3.

4、peterson演算法

該演算法非常簡單且有效,僅由兩個c函式構成:

關鍵的一點在於enter_region函式中的while迴圈,當兩個程序同時進入enter_region函式時,能夠確保先進入該函式的程序進入臨界區,而後進入的在while迴圈出等待。

5、tsl/xchg指令

tsl指令的形式如下:

tsl rx, lock    # 將lock讀入暫存器rx並將1寫入lock所在記憶體,讀和寫是乙個不可分割的原子操作

執行tsl的cpu將鎖住匯流排,這使得其它任何cpu都無法訪問共享記憶體,相當於遮蔽中斷的改進版。使用tsl指令的使用方法如下所示:

另一條指令xchg原子性地交換兩個位置的內容,所以它可作為tsl指令的替代品控制程序進入臨界區,原理實際上和上圖是一樣的,如下圖所示。所有的intel x86 cpu在底層同步中使用了xchg指令。

休眠與喚醒

上述方案有乙個共同的缺點就是程序在無法進入臨界區時,處於忙等待狀態,這浪費了cpu時間。要使程序在無法進入臨界區時阻塞,而不是等待,可以使用程序間通訊原語。例如:sleep、wakeup等。以下是另外一些程序間互斥、同步的方案。

1、訊號量

由大神dijkstra提出,它包括down(p,表示嘗試)和up(v,表示增加)兩種操作,所以又稱pv操作:

down:檢查訊號量的值是否大於0,大於0則減1並繼續,等於0就休眠程序,整個操作不可分割。

up:對訊號量值增1,喚醒由於down操作而休眠的程序,使其繼續執行未完成的down操作,整個操作不可分割。

訊號量可用於程序間的互斥和同步。

互斥:在同一時刻只有乙個程序能夠進行操作。例如互斥地進入臨界區。

同步:程序間的執行需要按照某種先後順序。例如生產者發現緩衝區滿時要停止;消費者發現緩衝區空時要停止。

使用訊號量解決生產者-消費者的例子:

其中,empty和full是用來實現同步的訊號量;mutex是用來實現互斥地訊號量。

2、互斥量

無計數能力,是訊號量的乙個簡化版本。互斥量包含兩個狀態:解鎖(0)和加鎖(1)。執行緒加鎖和解鎖函式mutex_lock、mutex_unlock的實現如下:

這裡的mutex_lock和上面的enter_region的區別在於:呼叫mutex_lock的執行緒無法進入臨界區時會釋放cpu(thread_yield函式)執行另外的執行緒;而呼叫enter_region會不斷迴圈測試(忙等待),直到臨界區可用。

3、管程

使用訊號量和互斥量存在乙個問題:死鎖。例如上面的訊號量部分**中,如果將down(&empty)和down(&mutex)順序對調,那麼就有可能發生死鎖。原因在於當生產者先鎖住mutex,然後empty為0休眠後,消費者由於得不到mutex鎖而休眠,這樣兩個程序將永遠休眠下去。使用管程可解決這一問題。管程由過程、變數、資料結構等組成的乙個模組,程序間必須互斥地訪問這個模組中的過程,如下圖所示。管程的重要特性是,在任一時刻管程中只能有乙個活躍程序。

上圖有乙個名為example的管程,包含乙個整型變數i、乙個條件變數c和兩個過程。管程為程序的互斥訪問提供了環境,接下來要解決的是同步問題。解決方法是使用條件變數:當管程中的過程發現自己無法繼續執行時(例如生產者發現緩衝區滿),會在某個條件變數身上執行wait操作阻塞自身並將其它程序調入管道;另乙個程序(如消費者)對緩衝區進行消費後,可以呼叫signal向條件變數傳送訊號以喚醒因呼叫wait而阻塞的程序(如生產者),然後自身退出管程,被喚醒的程序進入管程。

4、訊息傳遞

通過兩條原語send和receive在程序間進行通訊,send為傳送訊息而receive為接收訊息(有可能發生阻塞),也就是讓訊息稱為共享資源的載體。使用訊息傳遞機制解決生產者-消費者問題的**如下:

5、屏障

一種應用於程序組的同步機制。它規定,所有程序都完成了第n階段,才能進入第n+1階段。也就是說,當有程序完了第n階段而另一些程序沒有完成第n階段時,完成的那些程序是需要阻塞等待未完成程序的,如下圖所示。這可以在每個階段的末尾新增屏障來實現這一功能。

作業系統 程序通訊

學生實驗報告 實驗課名稱 計算機作業系統 實驗專案名稱 程序間通訊實驗 專業名稱 電腦科學與技術 一 實驗目的 linux系統的程序通訊機構 ipc 允許在任意程序間大批量地交換資料。本實驗的目的是了解和熟悉linux支援的訊息通訊機制 共享儲存區機制及資訊量機制。二 實驗要求 閱讀linux系統的...

作業系統 程序通訊

常用通訊模型 間接 通過作業系統核心 直接阻塞,被認為是同步的 非阻塞,被認為是非同步的 接收到訊號可能 類似軟中斷,停止正常執行。不適合傳遞資料 因為它傳遞的資訊很小,只是一位。僅起到通知作用。效率高。系統處理過程 註冊針對某個訊號的handler 一旦產生了訊號,作業系統收到訊號後,執行在核心態...

作業系統 程序通訊

程序通訊 程序之間的資訊交換 程序是分配系統資源的單位 包括記憶體位址空間 因此各程序擁有的記憶體位址空間相互獨立 共享儲存 1 兩個程序對共享空間的訪問必須是互斥的 2 基於資料結構的共享,慢是低階通訊 3 基於儲存區的共享,高階通訊,在記憶體中畫出一塊共享儲存區,資料形式儲存位置都由程序控制 訊...