linux同步機制之互斥鎖

 版權聲明:如有需要,可供轉載,但請註明出處:https://blog.csdn.net/City_of_skey/article/details/85494572

 

目錄

1、簡介

2、API

2.1 pthread_mutex_init

2.2 pthread_mutex_lock

2.3 pthread_mutex_trylock

2.4 pthread_mutex_timedlock

3.5 pthread_mutex_unlock

2.6 pthread_mutex_destroy

3、例子

4、比較


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、互斥鎖和信號量先比互斥鎖佔用空間比信號量小,效率比信號量高。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章