POSIX執行緒 互斥量

2021-07-30 03:33:01 字數 2188 閱讀 3611

為什麼需要互斥量

執行緒最大的好處是它們可以通過全域性變數來共享資訊。但這個好處也帶來了麻煩:有可能很多執行緒同時修改某乙個全域性變數,導致該全域性變數出現錯誤。我們必須制定某些規則,使執行緒對該全域性變數的修改不會導致錯誤。這個規則就是--同步。

posix執行緒使用互斥量來進行同步,「經驗表明,正確使用互斥量比使用通用訊號燈之類的其他同步模型要容易,還能很容易地使用互斥量與條件變數建立任何同步模型」—posix多執行緒程式設計-p39

當某個執行緒想修改某個共享資源時,它需要鎖住乙個互斥量;當其他執行緒需要訪問該資源時,它也要試圖鎖住同乙個互斥量。同步是自願的,參與者必須協同工作。如果某乙個執行緒不遵守設計好的規則,資料將被破壞。

術語

原子(atomic):不能被任何操作中斷的操作。

臨界區(critical section):一段可以訪問共享資源的**。該段**不能被另乙個想訪問該共享資源的執行緒打斷。簡單的說,臨界區是會影響到共享資源的**段。

mutex的初始化

靜態初始化

pthread_mutex_t mtx = ptherad_mutex_initializer

動態初始化

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);

注意點:

1.不能拷貝互斥量變數,因為使用拷貝的互斥量是不確定的。可以拷貝指向互斥量的指標,這樣就可以使多個函式或執行緒共享互斥量來實現同步。

2.必須保證每個互斥量在使用前被初始化,而且只被初始化一次。

3.如果需要初始化乙個非預設屬性的互斥量,必須使用動態初始化。

4.pthread_muteattr_t

的討論mutex的銷毀

int pthread_mutex_destroy(pthread_mutex_t *mutex);

注意點:

1.乙個被銷毀的互斥量,可以被pthread_mutex_init重新初始化。

2.在釋放互斥量占有的空間之前,最後先將互斥量解鎖和釋放。

mutex的操作

int pthread_mutex_lock(pthread_mutex_t *mutex);

int pthread_mutex_unlock(pthread_mutex_t *mutex);

另外兩個函式

int pthread_mutex_trylock(pthread_mutex_t *mutex)

int pthread_mutex_timelock(pthread_mutex_t *mutex, const struct timespec *abstime)

注意:互斥量不是免費的,它需要時間來加鎖和解鎖。所以,互斥量應該盡量少,夠用即可。互斥量的本質是序列執行。如果很多執行緒頻繁的加鎖同乙個互斥量,則執行緒的大部分時間是在等待,這對效能有損害。如果互斥量保護的資料報含彼此不相關的片段,則可以將大的互斥量分解為幾個小的互斥量來提高效能。

如何避免死鎖

當需要多個互斥量時,有乙個潛在的危險就是死鎖的出現。

最簡單的方法是把多個mutex定義為有層次的結構。比如,所有的執行緒都必須用某種相同的順序來獲得mutex。

鏈鎖是層次鎖的乙個特例,即兩個鎖的作用範圍互相交疊。當鎖住第乙個互斥量後,**進入乙個區域,該區域需要另乙個互斥量。當鎖住另乙個互斥量後,第乙個互斥量就不再需要了。這種技巧在遍歷如樹型結構或鍊錶結構時十分有用。每個節點設定乙個互斥量,而不是用乙個互斥量鎖住整個資料結構,阻止任何並行訪問。遍歷**可以首先鎖住佇列頭或根節點,找到期望的節點,鎖住它,然後釋放根節點或佇列互斥頭。這種技巧僅當多個執行緒總是活躍在層次中的不同部分時才應該使用鏈鎖。--posix多執行緒程式設計-p59。

另一種方法是「try and back off」,也就是呼叫pthread_mutex_trylock()。當該函式返回ebusy時,就釋放掉原來保持的所有mutex,然後再次嘗試。這種方法很沒有效率。

posix多執行緒 互斥量

1.互斥量初始化兩種方式 1 靜態初始化 include typedef struct my struct tag my struct t my struct t data int main int argc,char argv 2 動態初始化 include typedef struct my s...

POSIX訊號量實現互斥

採用posix訊號量實現互斥原語,實現執行緒間同步 採用訊號量實現互斥原語 include include include include include include include include include define maxnum 10000 用乙個結構體封裝命名訊號量 struct...

Posix多執行緒程式設計學習筆記(四) 互斥量(1)

一 什麼是互斥鎖 另一種在多執行緒程式中同步訪問手段是使用互斥量。程式設計師給某個物件加上一把 鎖 每次只允許乙個執行緒去訪問它。如果想對 關鍵部分的訪問進行控制,你必須在進入這段 之前鎖定一把互斥量,在完成操作之後再開啟它。互斥量函式有 pthread mutex init 初始化乙個互斥量 pt...