1. 程式人生 > >互斥鎖mutex簡單應用

互斥鎖mutex簡單應用

寫了段小程式碼學習互斥鎖的作用。
互斥鎖的作用:在程式設計中,引入了物件互斥鎖的概念,來保證共享資料操作的完整性。

思路是用2個執行緒對同一個記憶體位置buffer,進行寫和讀,為了防止2個執行緒同時對buffer進行修改,用同一把互斥鎖來限制。
寫操作簡化為把buffer修改為’W’,讀簡化為把buffer修改為’R’。
在對buffer進行修改之前用pthread_mutex_lock()進行加鎖,修改後pthread_mutex_unlock()解鎖。
程式碼如下:

#include<stdio.h>
#include<pthread.h>
#include
<unistd.h>
void reader_function(void); void writer_function(void); pthread_mutex_t mtx; //宣告互斥鎖mtx char buffer; int main(void) { pthread_mutex_init(&mtx, NULL); //用預設屬性初始化一個互斥鎖物件 pthread_t reader; //建立reader執行緒 pthread_create(&reader, NULL, (void*) reader_function, NULL); writer_function
();//執行writer } void writer_function(void) { int i; for(i=0; i<2; i++) { pthread_mutex_lock(&mtx); //對mtx上鎖 printf("Writer %d 已經對mtx上鎖了. \r\n",i); buffer = 'W'; printf("Writer %d 把buff修改為%c,\r\n",i, buffer); printf("Writer %d 解鎖mtx. \r\n\n\n", i); pthread_mutex_unlock(&mtx);//解鎖 sleep
(1); } } void reader_function(void) { int i; for(i=0; i<2; i++) { pthread_mutex_lock(&mtx); //對mtx上鎖 printf("Reader %d 已經對mtx上鎖了. \r\n",i); buffer = 'R'; printf("Reader %d 把buff修改為%c,\r\n",i, buffer); printf("Reader %d 解鎖mtx. \r\n\n\n", i); pthread_mutex_unlock(&mtx);//解鎖 sleep(1); } }

執行結果為:
在這裡插入圖片描述

進一步測試,把writer 的解鎖註釋掉,

void writer_function(void)
{
    int i;
    for(i=0; i<2; i++)
    {
        pthread_mutex_lock(&mtx);   //對mtx上鎖
        printf("Writer %d 已經對mtx上鎖了. \r\n",i);
        buffer = 'W';
        printf("Writer %d 把buff修改為%c,\r\n",i, buffer);
        //printf("Writer %d 解鎖mtx. \r\n\n\n", i);
        //pthread_mutex_unlock(&mtx);//解鎖
        sleep(1);
    }
}

執行結果如下:
在這裡插入圖片描述
可見,writer 0 修改了buffer後沒有解鎖mtx,而同線程的writer 1在sleep之後又對mtx加鎖,造成死鎖,執行緒一直掛起,reader 也因沒辦法加鎖而一直被掛起。

再上面的基礎上把reader 的加鎖註釋掉:

void reader_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		//pthread_mutex_lock(&mtx);	//對mtx上鎖
		//printf("Reader %d 已經對mtx上鎖了. \r\n",i);
		buffer = 'R';
		printf("Reader %d 把buff修改為%c,\r\n",i, buffer);
		printf("Reader %d 解鎖mtx. \r\n\n\n", i);
		pthread_mutex_unlock(&mtx);//解鎖
		sleep(1);
	}
}

執行結果如下:
在這裡插入圖片描述
結果說明了writer 執行緒對mtx的加鎖可以在reader 執行緒裡解鎖。

再把reader裡的解鎖註釋掉:

void reader_function(void)
{
	int i;
	for(i=0; i<2; i++)
	{
		//pthread_mutex_lock(&mtx);	//對mtx上鎖
		//printf("Reader %d 已經對mtx上鎖了. \r\n",i);
		buffer = 'R';
		printf("Reader %d 把buff修改為%c,\r\n",i, buffer);
		//printf("Reader %d 解鎖mtx. \r\n\n\n", i);
		//pthread_mutex_unlock(&mtx);//解鎖
		sleep(1);
	}
}

執行結果如下
在這裡插入圖片描述

reader現在跟互斥鎖沒關係,在writer死鎖一直掛起後,reader不受影響的執行,在這裡可以看出多執行緒程式的優點。

小結:互斥鎖可以保證同一資源在同一時間內只能被一個執行緒使用。
使用完資源後要記得解鎖,先後呼叫2次加鎖(中間沒有解鎖)會導致死鎖,執行緒一直掛起,其他使用此鎖的執行緒也會受到影響。
A執行緒加的鎖能被B執行緒解鎖。
對未加鎖的互斥鎖進行解鎖操作沒有意義。