【臨界資源】:多執行緒執行流共享的資源就叫做臨界資源
【臨界區】:每個執行緒內部,訪問臨界自娛的**,就叫做臨界區
【互斥】:任何時刻,互斥保證有且只有乙個執行流進入臨界區,訪問臨界資源,通常對臨界資源起保護作用
【原子性】:不會被任何排程機制打斷的操作,該操作只有兩態,要麼完成,要麼未完成
多個執行緒併發的操作共享變數,會帶來一些問題(看下面的**,思考為什麼會出現這種問題呢?)
//模擬實現乙個購票系統,發現現象
#include
#include
#include
int tickets =
1000
;void
*buyticket
(void
*arg)
else
} std:
:cout <<
"thread"
<< pthread_self <<
"quit..."
<< std:
:endl;
}int
main()
for( i =
0; i <
5; i++
)return0;
}
執行結果圖 :
出現這種現象主要是因為 :
要解決以上問題,需要做到以下三點:
1> **必須要有互斥行為:當**進入臨界區執行時,不允許其他執行緒進入該臨界區
2> 如果多個執行緒同時要求執行臨界區的**,並且臨界區沒有執行緒在執行,那麼只能允許乙個執行緒進入該臨界區
3> 如果執行緒不在臨界區中執行,那麼該執行緒不能阻止其他執行緒進入臨界區
要做到這三點,本質上就是需要一把鎖,linux 裡把提供的這把鎖叫互斥量
互斥量的介面
方法1 : 靜態分配
pthread_mutex_t mutex = pthread_mutex_initializer
方法2 : 動態分配
int
pthread_mutex_init
(pthread_mutex_t *restrict mutex,
const pthread_mutexattr_t*restrict attr)
;
引數:
mutex ——> 要初始化的互斥量
attr ——> null
int
pthread_mutex_destroy
(pthread_mutex_t *mutex)
;
銷毀互斥量需要注意:
– 使用pthread_ mutex_ initializer初始化的互斥量不需要銷毀
不要銷毀乙個已經加鎖的互斥量
– 已經銷毀的互斥量,要確保後面不會有執行緒再嘗試加鎖
int
pthread_mutex_lock
(pthread_mutex_t *mutex)
;int
pthread_mutex_unlock
(pthread_mutex_t *mutex);
返回值: 成功返回0,失敗返回錯誤號
呼叫pthread_ lock時,可能會遇到以下情況 :
– 互斥量處於未鎖狀態,該函式會將互斥量鎖定,同時返回成功
– 發起函式呼叫時,其他執行緒已經鎖定互斥量,或者存在其他執行緒同時申請互斥量,但沒有競爭到互斥量,那麼pthread_ lock呼叫會陷入阻塞(執行流被掛起),等待互斥量解鎖
優化上面的**:
#include
#include
#include
int tickets =
1000
; pthread_mutex_t lock;
void
*buyticket
(void
*arg)
else
pthread_mutex_unlock
(&lock)
;//解鎖
綜上 :加鎖之後,會使效能降低(加鎖之後,智慧型序列執行),但是增強了安全性互斥量實現原理**
Linux 執行緒同步與互斥
多個執行緒併發的操作共享變數,會帶來 些問題。假設兩個執行緒讀寫相同變數時,執行緒a讀取變數然後給這個變數賦予乙個新的值,但寫操作需要兩個儲存週期。當執行緒b在這兩個寫週期讀取這個變數時,可能會得到不一致的值。為了避免這個問題,就需要互斥,同一時間只允許乙個執行緒訪問該變數。假設乙個場景,現有100...
Linux 多執行緒同步與互斥
在linux的多執行緒同步與互斥中,主要提供了訊號量的同步方式,以及互斥鎖和條件變數等訪問共享資源的方式。訊號量主要用於執行緒間的同步操作,兩個執行緒協同完成一件事情,在乙個執行緒完成乙個動作後,該需要通知另外乙個執行緒,進行相應的操作。1.1 需要包含的標頭檔案 include1.2 定義乙個全域...
Linux 執行緒間的同步與互斥
執行緒同步 條件變數 為什麼使用條件變數?對臨界資源的時序可控性,條件滿足會通知其他等待操作臨界資源的執行緒,類似訊號。場景 t day展會排隊參觀 生產者消費者模型 條件變數是什麼?是一種同步機制,乙個執行緒用於修改這個變數使其滿足其它執行緒繼續往下執行的條件,其它執行緒則接收條件已經發生改變的訊...