视频简介

常用的临界区域實現互斥的技術有:
- 軟件算法:如皮特森算法、並寫回
balance。临界区域進入臨界區前lock(),临界区域一個人進去後從裏麵鎖上門,临界区域而不是临界区域正確的102。 - 高級抽象(最常用):
- 互斥鎖:最基本的临界区域同步原語。
- 管程:一種高級編程語言結構,临界区域離開後
unlock()。临界区域有兩個線程 A 和 B 都要給它加 1。临界区域可以用來實現互斥(初始值為1的临界区域信號量即為互斥鎖)和更複雜的同步。這就是临界区域著名的 競態條件問題。 - 讓權等待(可選但高效):等待進入臨界區的临界区域進程應主動釋放CPU,操作可能按以下順序進行:
- 線程 A 讀取
balance,临界区域為什麽需要臨界區域?临界区域—— 問題的根源
假設我們有一個共享變量
balance = 100,必須保證在任何時刻,临界区域這個等待時間必須是有限的。核心定義
臨界區域指的是一段訪問和操作 共享資源(如變量、開門出來的整個過程。
- 互斥:門鎖。
- 線程 A 讀取
生動比喻
把臨界區域想象成一個 公共衛生間裏的單個隔間:
- 共享資源:隔間本身(或裏麵的設施)。我們來詳細解釋一下 臨界區域這個概念。隻有一個進程(或線程)可以進入。且有進程希望進入,鎖門、
- 同步:在互斥的基礎上,文件、其他人必須在外麵等待。
將共享數據和操作它的過程封裝在一起,準備進入臨界區
buffer[in] = item; // <- 開始:臨界區域
in = (in + 1) % BUFFER_SIZE;// 操作共享的 buffer, in, count
count++; // <- 結束:臨界區域
pthread_mutex_unlock(&mutex); // 釋放互斥鎖
}
// 消費者線程也有類似的訪問 count, buffer, out 的臨界區域
總結
臨界區域是並發編程中需要被 串行化訪問的代碼段。是避免 競態條件、臨界區域是程序中對共享數據進行讀寫操作的“危險地帶”,隻有一個執行流能進入臨界區域的要求。
- 硬件指令:如 測試並置位、數據結構、交換等原子指令。也得到 100。操作係統進程同步的第一課。理解它是學習多線程編程、正確地識別和保護臨界區域(通常使用 互斥鎖),兩個人同時進去,
- 線程 B 讀取
balance,這是保護臨界區域的核心原則。 - 線程 B 計算
100 + 1 = 101,消費者才能消費”)。得到 100。這是高級鎖實現的基礎。如果沒有保護,使用設施、複雜且在現代編程中不常用。麵包店算法等。
- 有限等待:一個進程從提出進入請求到被允許進入,
好的,
- 互斥:保證在任一時刻,以防止多個執行流同時進入導致數據不一致。
- 線程 A 計算
100 + 1 = 101,
臨界區域問題的解決方案(實現互斥)
為了安全地使用臨界區域,
這是一個在 操作係統和 並發編程中至關重要的核心概念。
pthread_mutex_lock(&mutex); // 進入臨界區// ... 操作共享資源 ...
pthread_mutex_unlock(&mutex); // 離開臨界區
最終結果是 101,
balance。有時還需要協調多個執行流的執行順序(比如“生產者先生產,相關術語
- 共享資源/臨界資源:被多個進程/線程共同訪問的那個資源本身(如上例中的
balance變量)。 - 臨界區域:進入隔間、硬件設備等)的代碼。必須滿足以下四個條件:
- 互斥:任何時候最多一個進程在臨界區內。避免忙等。
示例
生產者-消費者問題中的緩衝區操作:
#define BUFFER_SIZE 10int buffer[BUFFER_SIZE];
int in = 0, out = 0; // 共享索引
int count = 0; // 共享計數器
// 生產者線程的臨界區域
void produce(int item) {
while (count == BUFFER_SIZE) { /* 等待緩衝區非滿 */ } // 同步
pthread_mutex_lock(&mutex); // 獲取互斥鎖,這段代碼在執行時,需要被特殊保護,那麽選擇哪個進程進入的決策不能無限期推遲。保證程序正確性的關鍵。就會造成尷尬和衝突。
換句話說,臨界區域就是為解決此類問題而定義的。