執行緒的同步與複用之 (互斥量)

2022-08-05 17:57:12 字數 1153 閱讀 1386

a. mutex (互斥量)

對於多執行緒的程式,訪問衝突的問題是很普遍的, 引入互斥用來保證在任一時刻,只能有一個執行緒訪問該物件, 來保證共享資料操作的完整性 。

解決的辦法是引入互斥鎖(mutex,mutual exclusive lock),獲得鎖的執行緒可以完成“讀-修改-寫”的操作,然後釋放鎖給其它執行緒,沒有獲得 鎖的執行緒只能等待而不能訪問共享資料,這樣“讀-修改-寫”三步操作組成一個原子操作,要麼 都執行,要麼都不執行,不會執行到中間被打斷,也不會在其它處理器上並行做這個操作。

//初始化

int pthread_mutex_init (pthread_mutex_t *__mutex, __const pthread_mutexattr_t *__mutexattr); 

pthread_mutex_t mlock = pthread_mutex_initializer;

//銷燬

int pthread_mutex_destroy (pthread_mutex_t *__mutex);

//try上鎖

int pthread_mutex_trylock (pthread_mutex_t *__mutex); 

//上鎖

int pthread_mutex_lock (pthread_mutex_t *__mutex); 

//解鎖

int pthread_mutex_unlock (pthread_mutex_t *__mutex);

一個執行緒可以呼叫pthread_mutex_lock獲得mutex,如果這時另一個執行緒已經呼叫 pthread_mutex_lock獲得了該mutex,則當前執行緒需要掛起等待,直到另一個執行緒呼叫 pthread_mutex_unlock釋放mutex,當前執行緒被喚醒,才能獲得該mutex並繼續執行。

如果一個執行緒既想獲得鎖,又不想掛起等待,可以呼叫pthread_mutex_trylock,如果mutex已 經被 另一個執行緒獲得,這個函式會失敗返回ebusy,而不會使執行緒掛起等待。

每個mutex有一個等待隊 列,一個執行緒要在mutex上掛起等待,首先在把自己加入等待佇列中,然後置執行緒狀態為睡眠,然 後呼叫排程器函式切換到別的執行緒。一個執行緒要喚醒等待佇列中的其它執行緒,只需從等待隊 列中取出一 項,把它的狀態從睡眠改為就緒,加入就緒佇列,那麼下次排程器函式執行時就有 可能切換到被喚醒的執行緒。

作業系統中的同步互斥(鎖與訊號量)

作業系統的同步與互斥可以從執行緒和程序兩個角度進行理解。如果從執行緒的角度理解,這裡本文以兩個執行緒為例,需要考慮這兩個執行緒是否屬於同一個程序,對於不同程序的執行緒來說,它們本質上和從兩個程序的角度進行理解是一樣的,在之後討論兩個程序間的同步互斥時會詳細說明。對於同一程序的兩個執行緒,假設有這樣一段 。 in...