天天看點

【Linux多線程】線程同步之互斥鎖

互斥鎖概念:鎖機制是同一時刻隻允許一個線程執行一個關鍵部分的代碼。

執行步驟說明

1. 初始化鎖

int pthread_mutex_init(pthread_mutex_t *mutex,const pthread_mutex_attr_t *mutexattr);

其中參數 mutexattr 用于指定鎖的屬性(見下),如果為NULL則使用預設屬性。

互斥鎖的屬性在建立鎖的時候指定,在LinuxThreads實作中僅有一個鎖類型屬性,不同的鎖類型在試圖對一個已經被鎖定的互斥鎖加鎖時表現不同。目前有四個值可供選擇:

(1)PTHREAD_MUTEX_TIMED_NP,這是預設值,也就是普通鎖。當一個線程加鎖以後,其餘請求鎖的線程将形成一個等待隊列,并在解鎖後按優先級獲得鎖。這種鎖政策保證了資源配置設定的公平性。

(2)PTHREAD_MUTEX_RECURSIVE_NP,嵌套鎖,允許同一個線程對同一個鎖成功獲得多次,并通過多次unlock解鎖。如果是不同線程請求,則在加鎖線程解鎖時重新競争。

(3)PTHREAD_MUTEX_ERRORCHECK_NP,檢錯鎖,如果同一個線程請求同一個鎖,則傳回EDEADLK,否則與PTHREAD_MUTEX_TIMED_NP類型動作相同。這樣就保證當不允許多次加鎖時不會出現最簡單情況下的死鎖。

(4)PTHREAD_MUTEX_ADAPTIVE_NP,适應鎖,動作最簡單的鎖類型,僅等待解鎖後重新競争。

2. 阻塞加鎖

int pthread_mutex_lock(pthread_mutex *mutex);

3. 非阻塞加鎖

int pthread_mutex_trylock( pthread_mutex_t *mutex);

該函數語義與 pthread_mutex_lock() 類似,不同的是在鎖已經被占據時傳回 EBUSY 而不是挂起等待。

4. 解鎖(要求鎖是lock狀态,并且由加鎖線程解鎖)

int pthread_mutex_unlock(pthread_mutex *mutex);

5. 銷毀鎖(此時鎖必需unlock狀态,否則傳回EBUSY)

int pthread_mutex_destroy(pthread_mutex *mutex);

代碼:

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include <unistd.h>
 
//對臨界區的保護問題
void *fun1(void *arg);
void *fun2(void *arg);
 
int buffer = 0;
pthread_mutex_t mutex;
int running = 1;
 
int main(void )
{
    pthread_t pt1;
    pthread_t pt2;
 
    pthread_mutex_init(&mutex,NULL);
 
    pthread_create(&pt1,NULL,fun1,(void*)&running);
    pthread_create(&pt2,NULL,fun2,(void*)&running);
 
    usleep(1000);
    running=0;
    pthread_join(pt1,NULL);
    pthread_join(pt2,NULL);
    pthread_mutex_destroy(&mutex);
    return 0;
}
 
void *fun1(void *arg)
{
    while(*(int *)arg)
    {
		//pthread_mutex_lock(&mutex);
		printf("in fun1 before add , buffer is : %d\n",buffer);
		usleep(2);
		buffer++;
		printf("in fun1 after sleep and add one ,now buffer is %d \n",buffer);
		//pthread_mutex_unlock(&mutex);
		usleep(2);
    }
}
 
void *fun2(void *arg)
{
    while(*(int *)arg)
    {
		//pthread_mutex_lock(&mutex);
		printf("in fun2 before add , buffer is : %d\n",buffer);
		usleep(2);
		buffer++;
		printf("in fun2 after sleep and add one ,now buffer is %d \n",buffer);
		//pthread_mutex_unlock(&mutex);
		usleep(2);
    }
 
}
           

gcc執行結果:

(1)添加互斥鎖結果

【Linux多線程】線程同步之互斥鎖

(2)删除互斥鎖的結果

【Linux多線程】線程同步之互斥鎖

繼續閱讀