在os引入多執行緒後,程式的多工併發功能得到了良好的支援,但同時也帶來了問題,那就是多執行緒併發會導致一些共享的資源產生競爭問題(例如對共享資料區的資料進行操作),而在計算機中,操作這種共享資源的**塊被稱為臨界區
。為了解決這種競爭衝突,我們必須理解兩個概念:同步
和互斥
。
互斥: 所謂互斥,就是說,任何時候只能有乙個物件訪問某個資源,絕不允許多個物件同時操作。即任何時候只能有乙個程序執行臨界區
**。
同步:所謂同步,指的是事件執行之間的依賴關係,譬如,事件b只有在事件a執行完畢後才能執行。在os多執行緒中,同步的引入是為了協調對共享資料的併發訪問。而為了確保同步的正確執行,基本來說有兩種方式:
通過底層硬體支援來完成(cpu指令中有test-and-set指令,即原子操作,所謂原子操作就是說,乙個操作要麼執行完成,要麼就不執行,決不可能執行到一半就停下來去做別的事情。)
高層次的軟體程式設計抽象。(程式設計難度較大)
大致如下圖所示:
訊號量,是os來協調共享資源訪問的一種重要的依賴資訊,它能確保執行緒之間的同步。簡單的理解,訊號量就是描述系統資源數量的乙個變數。
舉個生活中的例子,在乙個鐵軌的分叉點前,有個訊號燈,它可以來指示到來的火車是停在路口等還是可以進入路口,如下圖:
首先,這個並行的鐵軌上沒火車,訊號量為2,說明還有2個火車可以進入,
然後,有一輛火車來了到了入口,工作人員(模擬我們的os)發現訊號量是2(>0),於是讓這個火車進入,並把訊號量減1,此時訊號量為1.
然後,又一輛火車來了到了入口,工作人員發現訊號量是1(>0),於是讓這個火車進入,並把訊號量減1,此時訊號量為0.
這時,只要在並行軌道的火車還沒出去,只要有火車來了,就必須在路口等著(因為此時訊號量==0),直到有一輛在並行軌道的火車出去(火車出去時,工作人員會把訊號量進行加1操作)
ok,上面說到的訊號量減1操作,就是os中對訊號量的p()操作
(p是荷蘭語prolaag的縮寫,表示嘗試減少的意思);而訊號量加1操作,就是os中對訊號量的v()操作
(v是荷蘭語verhoog的縮寫,表示嘗試增加的意思)
假設訊號量是乙個整形變數,記為sem
p()操作:
sem-=1
if(sem<=0)
v()操作:
sem+=1
if(sem<=0) // 這裡是<=0,表明有其他執行緒在等待
訊號量與管程
記錄型訊號量 實現程序互斥 實現程序同步 實現前驅關係 生產者消費者問題 問題實現 相鄰的p操作的順序不能改變,否則會出現死鎖。實現互斥的p操作一定要實現同步的p操作之後。相鄰的v操作的順序可以改變。多生產者多消費者問題 問題實現 當緩衝區只有1時,沒有互斥訊號量也可以。吸菸者問題 問題實現 讀者寫...
作業系統訊號量和管程
同步互斥回顧 併發問題 競爭條件 競態條件 同步確保執行緒同步 訊號量是抽象資料型別 訊號量實現一般有兩種 訊號量可以用在兩個方面 用二值訊號量實現互斥功能 mutex new semaphore 1 初始化乙個值為1的訊號量作為乙個鎖 mutex p 訊號量減1 執行臨界區 此時如果有其他執行緒要...
訊號量管程解決同步問題
某網路系統有n個工作執行緒和1個排程服務程序,作線 星初始化時 守候佇列中等待 當使用者請求到達時,由服務程序喚醒工作執行緒執 若工執行緒守候隊列為空則則檢查請求等待佇列是否已滿 最多可存放m個使用者請求 未滿則將使用者請求放入等待佇列,否則拒絕使用者請求,工作執行緒執行結束時,檢查直請求等待佇列是...