1. 創建互斥量
pthreads 使用 pthread_mutex_t 類型的變量來表示互斥量,同時在使用互斥量進行同步前需要先對它進行初始化,可以用靜態或動態的方式對互斥量進行初始化。
(1)靜態初始化
對於靜態分配的 pthread_mutex_t 變量來說,只要將 PTHREAD_MUTEX_INITIALIZER賦給變量就行了。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
(2)動態初始化
對於動態分配或者不使用默認屬性的互斥變量來說,需要調用 pthread_mutex_int()函數來執行初始化工作。 pthread_mutex_int()函數原型如下:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
參數 mutex 是一個指向要初始化的互斥量的指針;參數 attr 傳遞 NULL 來初始化一個帶有默認屬性的互斥量,否則就要用類似於線程屬性對象所使用的方法,先創建互斥量屬性對象,再用該屬性對象來創建互斥量。
函數成功返回 0,否則返回一個非 0 的錯誤碼, 表 13.5 列出 pthread_mutex_init 出錯的錯誤碼。
靜態初始化程序通常比調用 pthread_mutex_init 更有效,而且在任何線程開始執行之前,確保變量被初始化一次。
2. 銷毀互斥量
銷毀互斥量使用 pthread_mutex_destroy()函數,原型如下:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
參數 mutex 指向要銷毀的互斥量。以下代碼銷毀了 mylock 互斥量:
int error; pthread_mutex_t mylock; if (error = pthread_mutex_destroy(&mylock)) fprintf(stderr, "Failed to destroy mylock : %s\n", strerror(error));
加鎖與解鎖
加鎖
pthreads 中有兩個試圖鎖定互斥量的函數, pthread_mutex_lock()和 pthread_mutex_trylock()。pthread_mutex_lock()函數會一直阻塞到互斥量可用為止,而 pthread_mutex_trylock()則嘗試加鎖, 但通常會立即返回。函數原型如下:
int pthread_mutex_lock(pthread_mutex_t *mutex); int pthread_mutex_trylock(pthread_mutex_t *mutex);
解鎖
pthread_mutex_unlock()函數用來釋放指定的互斥量。函數原型如下:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
死鎖的避免
當多個線程需要相同的一些鎖, 但是按照不同的順序加鎖, 死鎖就很容易發生, 如果能確保所有的線程都是按照相同的順序獲得鎖,那么死鎖就不會發生。 例如,規定程序內有三個互斥鎖的加鎖順序為 mutexA->mutexB->mutexC,則線程 t1、 t2、 t3 線程操作偽代碼如下所示: