詳解Linux系統(tǒng)編程——線程同步與互斥:互斥鎖
為什么需要互斥鎖?
在多任務操作系統(tǒng)中,同時運行的多個任務可能都需要使用同一種資源。這個過程有點類似于,公司部門里,我在使用著打印機打印東西的同時(還沒有打印完),別人剛好也在此刻使用打印機打印東西,如果不做任何處理的話,打印出來的東西肯定是錯亂的。
下面我們用程序模擬一下這個過程,線程一需要打印“ hello ”,線程二需要打印“ world ”,不加任何處理的話,打印出來的內容會錯亂:
運行結果如下:

實際上,打印機是有做處理的,我在打印著的時候別人是不允許打印的,只有等我打印結束后別人才允許打印。這個過程有點類似于,把打印機放在一個房間里,給這個房間安把鎖,這個鎖默認是打開的。當 A 需要打印時,他先過來檢查這把鎖有沒有鎖著,沒有的話就進去,同時上鎖在房間里打印。而在這時,剛好 B 也需要打印,B 同樣先檢查鎖,發(fā)現鎖是鎖住的,他就在門外等著。而當 A 打印結束后,他會開鎖出來,這時候 B 才進去上鎖打印。
而在線程里也有這么一把鎖——互斥鎖(mutex),互斥鎖是一種簡單的加鎖的方法來控制對共享資源的訪問,互斥鎖只有兩種狀態(tài),即上鎖( lock )和解鎖( unlock )。
互斥鎖的操作流程如下:
1)在訪問共享資源后臨界區(qū)域前,對互斥鎖進行加鎖。
2)在訪問完成后釋放互斥鎖導上的鎖。
3)對互斥鎖進行加鎖后,任何其他試圖再次對互斥鎖加鎖的線程將會被阻塞,直到鎖被釋放。
互斥鎖的數據類型是: pthread_mutex_t。
【文章福利】小編推薦自己的Linux內核技術交流群:【891587639】整理了一些個人覺得比較好的學習書籍、視頻資料共享在群文件里面,有需要的可以自行添加哦?。。。ê曨l教程、電子書、實戰(zhàn)項目及代碼)? ??


互斥鎖基本操作

以下函數需要的頭文件:
#include <pthread.h>
1)初始化互斥鎖
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
功能:
初始化一個互斥鎖。
參數:
mutex:互斥鎖地址。類型是 pthread_mutex_t 。 attr:設置互斥量的屬性,通??刹捎媚J屬性,即可將 attr 設為 NULL。
可以使用宏 PTHREAD_MUTEX_INITIALIZER 靜態(tài)初始化互斥鎖,比如: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 這種方法等價于使用 NULL 指定的 attr 參數調用 pthread_mutex_init () 來完成動態(tài)初始化,不同之處在于 PTHREAD_MUTEX_INITIALIZER 宏不進行錯誤檢查。 返回值:
成功:0,成功申請的鎖默認是打開的。
失?。悍?0 錯誤碼
2)上鎖
int pthread_mutex_lock(pthread_mutex_t *mutex);
功能:
對互斥鎖上鎖,若互斥鎖已經上鎖,則調用者一直阻塞,直到互斥鎖解鎖后再上鎖。
參數:
mutex:互斥鎖地址。
返回值:
成功:0
失?。悍?0 錯誤碼
int pthread_mutex_trylock(pthread_mutex_t *mutex);
調用該函數時,若互斥鎖未加鎖,則上鎖,返回 0;若互斥鎖已加鎖,則函數直接返回失敗,即 EBUSY。
3)解鎖
int pthread_mutex_unlock(pthread_mutex_t * mutex);
功能:
對指定的互斥鎖解鎖。
參數:
mutex:互斥鎖地址。
返回值:
成功:0
失?。悍?0 錯誤碼
4)銷毀互斥鎖
int pthread_mutex_destroy(pthread_mutex_t *mutex);
功能:
銷毀指定的一個互斥鎖?;コ怄i在使用完畢后,必須要對互斥鎖進行銷毀,以釋放資源。
參數:
mutex:互斥鎖地址。
返回值:
成功:0
失?。悍?0 錯誤碼
互斥鎖應用實例 我們通過互斥鎖完善上面的例子,示例代碼如下:
運行結果如下:

