版權聲明:如有需要,可供轉載,但請註明出處:https://blog.csdn.net/City_of_skey/article/details/85494572
目錄
1、簡介
linux多線程的環境中爲了保證變量的同步需要使用互斥鎖mutex,當一個線程使用互斥鎖時,另一個線程就會阻塞進入睡眠狀態。互斥鎖本質上是信號量的一個特例,信號量是可以多個線程共享資源,而互斥鎖同時只能一個進程使用資源。互斥鎖不能使用在中斷因爲中斷不能休眠。互斥鎖也不能遞歸
2、API
2.1 pthread_mutex_init
互斥鎖的初始化有兩種:動態初始化、靜態初始化,動態初始化調用pthread_mutex_init,一般默認是缺省模式所以,第二個參數是NULL,
pthread_mutex_init(&lock, NULL)
靜態初始化是調用宏 PTHREAD_MUTEX_INITIALIZER
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER
2.2 pthread_mutex_lock
這個函數就會加鎖,如果已經被鎖住那麼線程就會阻塞進入休眠,如果加鎖成功那麼其他進程就不能就會進入阻塞休眠狀態。
2.3 pthread_mutex_trylock
這個函數在Pthread_mutex_lock的基礎上做了改進,調用該函數如果沒有獲取鎖就會返回EBUSY錯誤碼,表示該鎖已經被其他線程佔用,立即返回而不是進入阻塞狀態。
2.4 pthread_mutex_timedlock
pthread_mutex_timedlock是在pthread_mutex_lock的基礎上添加了超時時間,如果超過了這個時間還沒有獲取鎖就返回,返回錯誤碼ETIMEDOUT,第二個參數是超時時間變量struct timespec abs_timeout。
struct timespec abs_timeout;
abs_timeout.tv_sec = time(NULL) + 1;
abs_timeout.tv_nsec = 0;
3.5 pthread_mutex_unlock
釋放鎖
2.6 pthread_mutex_destroy
銷燬互斥鎖,釋放空間。
3、例子
不加互斥鎖:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
int g_val = 0;
void *fun1(void *argv){
int i = 0;
for(i = 0; i < 10000; ++i){
g_val += 1;
}
}
int main(){
pthread_t t1, t2;
pthread_create(&t1, NULL, fun1, NULL);
pthread_create(&t2, NULL, fun1, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("g_val:%d\n", g_val);
}
運行結果:
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:19839
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:11580
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
因爲兩個線程同時對全局變量g_val做加的操作而沒有加鎖,最終g_val的值是不確定的。
加互斥鎖:
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int g_val = 0;
void *fun1(void *argv){
int i = 0;
for(i = 0; i < 10000; ++i){
pthread_mutex_lock(&lock);
g_val += 1;
pthread_mutex_unlock(&lock);
}
}
int main(){
pthread_t t1, t2;
pthread_create(&t1, NULL, fun1, NULL);
pthread_create(&t2, NULL, fun1, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock);
printf("g_val:%d\n", g_val);
}
運行結果:
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
root@ubuntu:/home/c_test/mutex# ./a.out
g_val:20000
加了互斥鎖後每次運行結果都是20000.
4、比較
1、當沒有獲取鎖時互斥鎖就會阻塞進入休眠狀態,但自旋鎖不會休眠會一致在等待,如果資源鎖定時間短用自旋鎖的效率更高,內核開發中使用自旋鎖比較多,但如果資源鎖定時間長建議使用互斥鎖。自旋鎖不會休眠如果資源要休眠建議使用互斥鎖、信號量。
2、互斥鎖和信號量先比互斥鎖佔用空間比信號量小,效率比信號量高。