多執行緒互斥鎖訪問演算法(上)------Peterson演算法
你好!這裡是風箏的部落格,
歡迎和我一起交流。
在多執行緒存在的環境中,除了堆疊中的臨時資料之外,所有的資料都是共享的。如果我們需要執行緒之間正確地執行,那麼務必需要保證公共資料的執行和計算是正確的。簡單一點說,就是保證資料在執行的時候必須是互斥的。否則,如果兩個或者多個執行緒在同一時刻對資料進行了操作,那麼後果是不可想象的。
那麼,該怎麼去實現一個資源(資料)的互斥訪問呢?
那就是這章所講的Peterson演算法,它可以控制兩個執行緒訪問一個共享的單使用者資源而不發生訪問衝突。Gary L. Peterson於1981年提出此演算法 。
我們看下程式碼實現:
#define true 1
#define false 0
int lock;
int hold [2]={false};
void enter_lock(int thread_id)
{
hold[thread_id]=true;/*標記佔有資源*/
lock=thread_id;
while(lock==thread_id&&(hold[1-thread_id]==true));/*阻塞,等待排程*/
}
void exit_lock(int thread_id)
{
hold[thread_id]=false;/*標記釋放資源*/
}
這就是Peterson演算法的核心程式碼,當我們需要訪問臨界區(互斥資源)時:
void process_0(void)//執行緒0
{
enter_lock(0);
//臨界區
//訪問資源
exit_lock(0);
}
void process_1(void)//執行緒1
{
enter_lock(1);
//臨界區
//訪問資源
exit_lock(1);
}
我們可以來模擬一下:
當有兩個執行緒(執行緒A,thread_id=0、執行緒B,thread_id=1)來搶佔資源時,
我們可以假設三種情況來模擬:
一:當執行緒B不佔有資源但是執行緒A想佔有資源時,
執行緒A的enter_lock函式while裡&&右邊條件不成立,所以while不成立,執行緒A成功佔有資源。
二:當執行緒B正在佔有資源,但是系統發生排程使得執行緒A也想佔有資源時,
執行緒A的enter_lock函式裡while成立,使得執行緒A函式阻塞,
待執行緒B呼叫exit_lock函式後才會使得執行緒A裡的while得以向下執行。
三:當執行緒B執行:”lock=thread_id;”語句之後,系統發生呼叫使得執行緒A也想佔有資源時,
執行緒A的enter_lock函式裡while成立,使得執行緒A函式阻塞,當系統排程使得執行緒B繼續執行時,
因為全域性變數lock被執行緒A更改了,所以執行緒B中while不成立,執行緒B成功佔有資源,待執行緒B釋放資源後,
執行緒A中while右半部不成立,所以也使得執行緒A佔有資源。
顯然易見,Peterson演算法有個侷限性,他只支援兩個執行緒,如果在多一個執行緒,則會出現錯誤。
為了解決這個問題,下一章會講另一種演算法:多執行緒互斥鎖訪問演算法(下)——Lamport演算法(麵包店演算法)
Peterson演算法不需要原子(atomic)操作,它是純軟體途徑解決了互斥鎖的實現。但需要注意限制CPU對記憶體的訪問順序的優化改變(編譯器的一個優化點)。因為它依賴於這個時序實現:
先寫入hold[thread_id]=true;再寫入lock=thread_id;,否則會出現死鎖。
相關文章
- 多執行緒互斥鎖訪問演算法(下)------Lamport演算法(麵包店演算法)執行緒演算法LAMP
- 多執行緒(2)-執行緒同步互斥鎖Mutex執行緒Mutex
- 執行緒同步與互斥:互斥鎖執行緒
- 執行緒的互斥鎖執行緒
- Linux多執行緒的使用一:互斥鎖Linux執行緒
- 畫江湖之 PHP 多執行緒開發 【執行緒安全 互斥鎖】PHP執行緒
- 畫江湖之 PHP 多執行緒開發 [執行緒安全 互斥鎖]PHP執行緒
- python多執行緒程式設計3: 使用互斥鎖同步執行緒Python執行緒程式設計
- Linux之執行緒互斥鎖Linux執行緒
- linux程式多執行緒互斥鎖的簡單使用Linux執行緒
- 執行緒安全: 互斥鎖和自旋鎖(10種)執行緒
- 多執行緒鎖的問題執行緒
- windows多執行緒同步--互斥量Windows執行緒
- Java多執行緒中執行緒安全與鎖問題Java執行緒
- 多執行緒_鎖執行緒
- Java多執行緒—執行緒同步(單訊號量互斥)Java執行緒
- 多執行緒之8鎖問題執行緒
- C++11多執行緒程式設計(二)——互斥鎖mutex用法C++執行緒程式設計Mutex
- windows多執行緒同步互斥--總結Windows執行緒
- Java多執行緒(2)執行緒鎖Java執行緒
- Java多執行緒/併發12、多執行緒訪問static變數Java執行緒變數
- Linux Qt使用POSIX多執行緒條件變數、互斥鎖(量)LinuxQT執行緒變數
- Java 多執行緒併發程式設計之互斥鎖 Reentrant LockJava執行緒程式設計
- 執行緒安全佇列(使用互斥鎖進行實現)執行緒佇列
- peterson演算法演算法
- iOS多執行緒安全-13種執行緒鎖?iOS執行緒
- “生命遊戲”的多執行緒演算法思考遊戲執行緒演算法
- 多執行緒-死鎖問題概述和使用執行緒
- java多執行緒–同步鎖Java執行緒
- Java多執行緒-無鎖Java執行緒
- C#多執行緒學習(六) 互斥物件C#執行緒物件
- C# 多執行緒學習(6) :互斥物件C#執行緒物件
- Gil全域性解釋鎖和執行緒互斥鎖的關係執行緒
- linux多執行緒-----同步機制(互斥量、讀寫鎖、條件變數)Linux執行緒變數
- 多執行緒非同步安全,安全鎖的問題執行緒非同步
- Java多執行緒(五):死鎖Java執行緒
- java多執行緒(5)死鎖Java執行緒
- Python 多執行緒和鎖Python執行緒