视频简介
如果沒有保護,临界区域

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