互斥鎖mutex簡單應用
阿新 • • 發佈:2018-11-21
寫了段小程式碼學習互斥鎖的作用。
互斥鎖的作用:在程式設計中,引入了物件互斥鎖的概念,來保證共享資料操作的完整性。
思路是用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執行緒解鎖。
對未加鎖的互斥鎖進行解鎖操作沒有意義。