續接上一篇“線程同步”:https://blog.csdn.net/zy010101/article/details/105967289
本文講述讀寫鎖。讀寫鎖和互斥量不太一樣,它允許鎖可以是讀加鎖,寫加鎖以及未加鎖三種狀態。每次只能由一個線程處於寫加鎖狀態,但是可以有多個線程處於讀加鎖狀態。
讀寫鎖是一把鎖,不是兩把鎖。它就像是多路開關一樣。當鎖處於寫加鎖狀態時,所有其他試圖對這個鎖進行讀加鎖或者寫加鎖的線程都會被阻塞;當鎖處於讀加鎖狀態時,所有試圖對這個鎖進行讀加鎖的線程頭可以得到訪問權,而所有試圖對這個鎖進行寫加鎖的線程都會被阻塞。
讀寫鎖很明顯帶來了比互斥量更高的併發性。並且讀寫鎖非常適合讀取比寫入操作更多的情況。有的教材會把讀寫鎖也稱爲“共享互斥鎖”。當讀寫鎖以寫模式鎖住,稱之爲“共享模式鎖住”;而當讀寫鎖以讀模式鎖住,稱之爲“互斥模式鎖住”。
下面是供我們在POSIX下進行讀寫鎖初始化和銷燬的函數。
下面是與寫加鎖的函數。
下面是與讀加鎖的函數。
由於讀寫鎖是一把鎖,因此在解鎖的時候無論你是讀加鎖,還是寫加鎖,都是使用下面的解鎖函數。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
char str[30]; //共享資源
pthread_rwlock_t rwlock; //讀寫鎖
void *th_write(void *arg)
{
usleep(300); //延時
pthread_rwlock_wrlock(&rwlock);
strcpy(str,"123");
pthread_rwlock_unlock(&rwlock);
pthread_exit(NULL);
}
void *th_read(void *arg)
{
pthread_rwlock_rdlock(&rwlock);
printf("read: %s\n",str);
pthread_rwlock_unlock(&rwlock);
pthread_exit(NULL);
}
int main(void)
{
int i;
pthread_t tid[8];
strcpy(str,"Hello World!");
pthread_rwlock_init(&rwlock, NULL); //初始化鎖
for (i = 0; i<3; i++) //3和寫線程
pthread_create(&tid[i], NULL, th_write, NULL);
for (i = 0; i<5; i++) //5個讀線程
pthread_create(&tid[i+3], NULL, th_read, NULL);
for (i = 0; i<8; i++) //等待線程結束,回收線程
pthread_join(tid[i], NULL);
pthread_rwlock_destroy(&rwlock); //銷燬鎖
return 0;
}
運行結果如下:
可以看到,可以多個讀線程去訪問讀加鎖的資源。並且寫加鎖只能被某個線程獨自訪問。其餘線程都在阻塞。並且等待線程中的寫加鎖線程比讀加鎖線程優先級高。
總結一下:
讀共享,寫獨享;寫必讀優先級高。