1、競爭條件
兩個或多個程序/執行緒讀寫某些共享資料時,結果取決於其cpu排程的執行次序,這種現象稱為競爭條件
2、互斥
以某種手段確保當乙個程序/執行緒在使用乙個共享變數或檔案時,其他程序/執行緒不能做同樣的操作
3、臨界區
把對共享記憶體進行訪問的程式片段稱為臨界區,如果能使得兩個程序/執行緒不同時處於臨界區,就能夠避免競爭條件
4、幾種互斥方案
遮蔽中斷、原子操作、鎖、自旋鎖、多元訊號量(又名訊號量)、二元訊號量、讀寫鎖、互斥量、條件變數
1)遮蔽中斷
在單處理器中,使每個程序剛進入臨界區後就立即遮蔽中斷,在就要離開臨界區之前再開啟中斷,遮蔽中斷之後,時鐘中斷也會被遮蔽,由於cpu只有在發生時中中斷或其他中斷時才會進行程序切換,這樣,在遮蔽中斷之後,cpu將不會被切換到其他程序,因此此時不必擔心其他程序介入
存在的問題:多核無效、
2)鎖一種軟體解決方案,使用乙個共享鎖變數,初始值設為0,每個程序進入臨界區以前先訪問該鎖變數,檢查其值是否為0
存在的問題:在乙個程序訪問到值為0 ,並將其修改為1之前,另乙個程序可能會訪問到其值為0,因為這個操作不是原子的
3)嚴格輪換法(自旋鎖)
thread1:
while(
true)
thread2:
while(
true)
如上述**所示:執行緒2會連續測試變數turn直到其值為1,這稱為忙等待,用於忙等待的鎖稱為自旋鎖。
存在的問題:解決了2)中的問題,但是這種忙等待很浪費cpu時間,而且如果執行緒1 sleep,會導致執行緒2一直迴圈
4)原子操作
原子操作即是指一組相關的操作要麼都不間斷的執行,要麼都不執行
原子操作:單指令操作,在程式的執行過程中,單指令操作不會被打斷,而對於非原子操作:比如++i(首先讀取i到某個暫存器x;然後執行x++;最後將x的內容儲存回i),由於其任何一部都有可能被打斷,因此不是執行緒安全的。在windows上,有一套api專門進行原子操作,比如:interlockedexchange:原子地交換兩個值;interlockeddecrement:原子地減少乙個值;interlockedincrement:原子地增加乙個值...。然而,有乙個問題是,對於複雜的資料結構或者操作,我們並不能很容易甚至不能實現原子操作,因此,為了保證執行緒安全,我們還需要其他的執行緒同步機制。
5)(多元)訊號量
多元訊號量,顧名思義,可以允許多個執行緒併發訪問資源,乙個初始值為n的訊號量允許n個執行緒併發訪問,執行緒通過訊號量訪問資源時會執行如下操作:
1)將訊號量減1;
2)如果訊號量的值<0,則進入等待狀態,否則訪問資源;
3)訪問資源結束以後,執行緒釋放訊號量,即將訊號量的值加1;
4)如果訊號量的值小於1,喚醒乙個等待中的執行緒。
6)二元訊號量
二元訊號量是最簡單的一種鎖,只有兩種狀態:占用與非占用。二元訊號量適用於只能被乙個執行緒所訪問的資料或資源。當二元訊號量處於非占用狀態時,第乙個試圖該二元訊號量的執行緒會獲得該鎖(二元訊號量);當其為占用狀態時,任何試圖獲取該二元訊號量的執行緒都必須等待指導該二元訊號量被釋放。
7)互斥量
互斥量的作用與二元訊號量相同,區別在於:同乙個訊號量可以被系統中的乙個執行緒獲取之後由另乙個執行緒釋放(因為訊號量其實就是乙個計數機制,任何執行緒都可以更改這個計數值,計數值減為0,即該鎖釋放),而互斥量要求執行緒的獲取和釋放必須由同乙個執行緒進行,其他執行緒無法釋放互斥量
互斥量常和條件變數一起使用、互斥量是乙個可以處於兩態之一的變數:解鎖和加鎖,0表示解鎖,其他所有值均表示加鎖
pthread中的互斥量mutex
函式呼叫:
pthread_mutex_t mutex
pthread_mutex_init:建立乙個互斥量
pthread_mutex_destory:撤銷乙個已經存在的互斥量
pthread_mutex_lock:獲得乙個鎖/加鎖,若失敗則阻塞
pthread_mutex_trylock:加鎖,若失敗則返回乙個錯誤,不會阻塞
pthread_mutex_unlock:釋放鎖
8)條件變數
使用條件變數可以讓多個執行緒一起等待某個事件的發生,當事件發生即條件變數被喚醒時,所有執行緒可以一起恢復執行。
條件變數不是計數器,條件變數也不能像訊號量那樣積累訊號以便以後使用。所以,如果向乙個條件變數傳送訊號,但是在該條件變數上並沒有等待程序,則該訊號會永遠丟失,也就是說,wait操作必須在signal操作之前
例如條件變數和互斥量結合解決生產者消費者問題
pthread_cond_t condc
pthread_cond_init:建立乙個條件變數
pthread_cond_destroy:撤銷乙個條件變數
pthread_cond_wait:阻塞以等待乙個訊號
pthread_cond_signal:向另乙個執行緒發起乙個訊號來喚醒它
pthread_cond_broadcast:向多個執行緒發起訊號來讓它們全部喚醒
9)讀寫鎖
對於共享資源的操作無外乎就是讀取與重寫,讀取不會引起執行緒同步問題,只有寫操作才會帶來執行緒同步問題,因此,對於讀取操作遠遠頻繁與寫操作的情況,上述同步機制會顯得十分低效。因此,引入了讀寫鎖。讀寫鎖有三種狀態:自由、共享、獨佔。有兩種獲取方式:以共享方式獲取、以獨佔方式獲取。自由狀態下,兩種方式均可獲取該鎖;共享狀態下,可以共享方式獲取該鎖,如果以獨佔方式獲取該鎖必須等待,直到所有使用該鎖的執行緒釋放鎖;獨佔狀態下,兩種獲取方式均需要等待。
程序執行緒間同步
一 posix訊息佇列 通過固定名稱來建立和引用訊息佇列 1.可以認為是乙個訊息鍊錶,有足夠的許可權的執行緒可以往佇列中放置和獲取訊息。2.可指定優先順序 在空佇列放置訊息時候能夠產生乙個訊號或啟動乙個執行緒 3.建立訊息佇列mq open mq close 關閉 並不刪除 mq unlink 刪除...
程序間通訊 和 執行緒間同步
前經常搞混,所以記錄下來。程序間通訊主要是指多個程序間的資料互動。而執行緒間同步主要指維護多個執行緒之間資料準確 一致性。一.程序間通訊主要有以下幾種方式 管道 pipe 管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的程序間使用。程序的親緣關係通常是指父子程序關係。有名管道 ...
程序 執行緒間同步機制。
一 程序 執行緒間同步機制。臨界區 互斥區 事件 訊號量四種方式 臨界區 critical section 互斥量 mutex 訊號量 semaphore 事件 event 的區別 1 臨界區 通過對多執行緒的序列化來訪問公共資源或一段 速度快,適合控制資料訪問。在任意時刻只允許乙個執行緒對共享資源...