Linux多執行緒互斥鎖

2021-08-18 18:29:36 字數 4239 閱讀 2954

多執行緒程式設計中,(多執行緒程式設計)可以用互斥鎖(也稱互斥量)可以用來保護關鍵**段,以確保其獨佔式的訪問,這有點像二進位制訊號量。posix互斥鎖相關函式主要有以下5個:

[cpp]view plain

copy

#include 

intpthread_mutex_init(pthread_mutex_t *mutex, 

const

pthread_mutexattr_t *mutexattr);  

intpthread_mutex_destroy(pthread_mutex_t *mutex);  

intpthread_mutex_lock(pthread_mutex_t *mutex);  

intpthread_mutex_trylock(pthread_mutex_t *mutex);  

intpthread_mutex_unlock(pthread_mutex_t *mutex);  

這些函式第乙個引數mutex指向要操作的目標互斥鎖,成功時返回0,出錯返回錯誤碼

l  pthread_mutex_init用於初始化互斥鎖,mutexattr用於指定互斥鎖的屬性,若為null,則表示預設屬性。除了用這個函式初始化互斥所外,還可以用如下方式初始化:pthread_mutex_t mutex = pthread_mutex_initializer;

l  pthread_mutex_destroy用於銷毀互斥鎖,以釋放占用的核心資源,銷毀乙個已經加鎖的互斥鎖將導致不可預期的後果

l  pthread_mutex_lock以原子操作給乙個互斥鎖加鎖。如果目標互斥鎖已經被加鎖,則pthread_mutex_lock則被阻塞,直到該互斥鎖佔有者把它給解鎖

l  pthread_mutex_trylock和pthread_mutex_lock類似,不過它始終立即返回,而不論被操作的互斥鎖是否加鎖,是pthread_mutex_lock的非阻塞版本。當目標互斥鎖未被加鎖時,pthread_mutex_trylock進行加鎖操作;否則將返回ebusy錯誤碼。注意:這裡討論的pthread_mutex_lock和pthread_mutex_trylock是針對普通鎖而言的,對於其他型別的鎖,這兩個加鎖函式會有不同的行為

l  pthread_mutex_unlock以原子操作方式給乙個互斥鎖進行解鎖操作。如果此時有其他執行緒正在等待這個互斥鎖,則這些執行緒中的乙個將獲得它

互斥鎖示例程式:

[cpp]view plain

copy

#include 

#include 

#include 

#define err_sys(msg) \do 

while

(0)  

#define err_exit(msg) \do 

while

(0)  

intglab = 1;  

void

*r1(

void

*arg)  

return

"r1 over"

;  }  

void

*r2(

void

*arg)  

return

"r2 over"

;  }  

intmain(

void

)    

pthread_mutexattr_t結構體定義了一套完整的互斥鎖屬性。執行緒庫提供了一系列函式來操作pthread_mutexattr_t型別變數,以方便我們獲取和設定互斥鎖屬性。一下是一些主要的函式:

[cpp]view plain

copy

#include 

intpthread_mutexattr_destroy(pthread_mutexattr_t *attr);  

intpthread_mutexattr_init(pthread_mutexattr_t *attr);  

intpthread_mutexattr_getpshared(

const

pthread_mutexattr_t *restrict attr, 

int*restrict pshared);  

intpthread_mutexattr_setpshared(pthread_mutexattr_t *attr, 

intpshared);  

intpthread_mutexattr_gettype(

const

pthread_mutexattr_t *restrict attr, 

int*restrict type);  

intpthread_mutexattr_settype(pthread_mutexattr_t *attr, 

inttype);  

互斥鎖兩種常用屬性:pshared和type

互斥鎖屬性pshared指定是否允許跨程序共享互斥鎖,其可選值有兩個:

l  pthread_process_shared。互斥鎖可以被跨程序共享。

l  pthread_process_private。互斥鎖只能被和鎖的初始化執行緒隸屬於同乙個程序的執行緒共享。

互斥鎖屬性type指定互斥鎖的型別。linux支援如下4種型別的互斥鎖:

l  pthread_mutex_normal,普通鎖。這是互斥鎖預設的型別。當乙個執行緒對乙個普通鎖加鎖以後,其餘請求該所的執行緒將形成乙個等待佇列,並在該所解鎖後按優先順序獲得它。這種鎖型別保證了資源分配的公平性。但這種鎖也很容易引發問題:乙個執行緒如果對乙個已經加鎖的普通鎖再次加鎖,將引發死鎖;對乙個已經被其他執行緒加鎖的普通鎖解鎖,或者對乙個已經解鎖的普通鎖解鎖將導致不可預期的後果。

l  pthread_mutex_errorcheck,檢錯鎖。乙個執行緒如果對乙個已經加鎖的檢錯鎖再次加鎖,則加鎖操作返回edeadlk。對乙個已經被其讓他執行緒加鎖的檢錯鎖解鎖,或者對乙個已經解鎖的檢錯鎖再次解鎖,則檢錯鎖返回eperm。

l  pthream_mutex_recursive,巢狀鎖。這種鎖允許乙個執行緒在釋放鎖之前對他加鎖而不發生死鎖。不過其他執行緒如果要獲得這個鎖,則當前鎖的擁有者必須執行相應次數的解鎖操作。對乙個已經被其他執行緒枷鎖的巢狀鎖解鎖,或者對乙個已經解鎖的巢狀鎖再次解鎖,則解鎖操作返回eperm。

l  pthread_mutex_default,預設鎖。乙個執行緒如果對乙個已經加鎖的預設鎖再次加鎖,或者對乙個已經被其他執行緒加鎖的預設鎖解鎖,或者對乙個已經解鎖的預設鎖再次解鎖,將導致不可預期的後果。

使用巢狀鎖(pthream_mutex_recursive)程式示例

[cpp]view plain

copy

#include 

#include 

#include 

inta = 1;  

intb = 1;  

pthread_mutex_t mutex;  

void

*pthread1(

void

*arg)  

if(pthread_mutex_lock(&mutex) != 0) 

/* 此時呼叫了2次lock操作 */

a++;  

b++;  

if(a != b)  

printf("pthread1: %d, %d\n"

, a, b);  

else

printf("11\n"

);  

pthread_mutex_unlock(&mutex);  

pthread_mutex_unlock(&mutex);  

sleep(1);  

}  }  

void

*pthread2(

void

*arg)  

a++;  

b++;  

if(a != b)  

printf("pthread2: %d, %d\n"

, a, b);  

else

printf("22------------\n"

);  

pthread_mutex_unlock(&mutex);  

sleep(1);  

}  }  

intmain(

void

)    參考:

1、《linux高效能伺服器程式設計》第14章 多執行緒程式設計/互斥鎖

2、linux多執行緒程式設計

3、linux多執行緒程式設計-訊號量

linux多執行緒(互斥鎖)

當多個執行緒想要對同乙個資源進行操作的時候,為了使得不出現髒讀的情況,要用互斥鎖來規定執行緒的先後順序。互斥鎖和訊號量的作用類似。鎖的資料型別 pthread mutex t mutes 鎖的初始化 int pthread mutex init pthread mutex t const pthre...

Linux多執行緒程式設計 執行緒互斥鎖

通過下面的練習加深對執行緒的概念的理解,同時明確執行緒的控制。從而進一步了解執行緒的互斥,並學會利用pthread庫。定義乙個用於互斥的互斥鎖 和乙個主函式和兩個子執行緒都能訪問的共享變數,乙個主函式和兩個用來建立子執行緒的子函式 在主函式中定義兩個子執行緒id的變數,初始化互斥鎖,建立對應函式的子...

Linux多執行緒同步 互斥鎖

當多個執行緒對同乙個資源進行訪問的時候,為了這個資源的安全性,我們需要對這個資源進行鎖定,規定同一時間只有乙個資源能夠獲得該鎖的鑰匙,其它執行緒要獲得該資源需要等待該執行緒 互斥鎖建立 pthread mutex t mutex 互斥鎖初始化 mutex pthread mutex initiali...