POSIX读写锁

2020-05-18 15:50:33 浏览数 (2)

续接上一篇“线程同步”:https://cloud.tencent.com/developer/article/1629556

本文讲述读写锁。读写锁和互斥量不太一样,它允许锁可以是读加锁,写加锁以及未加锁三种状态。每次只能由一个线程处于写加锁状态,但是可以有多个线程处于读加锁状态。

读写锁是一把锁,不是两把锁。它就像是多路开关一样。当锁处于写加锁状态时,所有其他试图对这个锁进行读加锁或者写加锁的线程都会被阻塞;当锁处于读加锁状态时,所有试图对这个锁进行读加锁的线程头可以得到访问权,而所有试图对这个锁进行写加锁的线程都会被阻塞。

读写锁很明显带来了比互斥量更高的并发性。并且读写锁非常适合读取比写入操作更多的情况。有的教材会把读写锁也称为“共享互斥锁”。当读写锁以写模式锁住,称之为“共享模式锁住”;而当读写锁以读模式锁住,称之为“互斥模式锁住”。

下面是供我们在POSIX下进行读写锁初始化和反向初始化的函数。

下面是与写加锁的函数。

下面是与读加锁的函数。

由于读写锁是一把锁,因此在解锁的时候无论你是读加锁,还是写加锁,都是使用下面的解锁函数。

代码语言:javascript复制
#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: %sn",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;        
}

运行结果如下:

可以看到,可以多个读线程去访问读加锁的资源。并且写加锁只能被某个线程独自访问。其余线程都在阻塞。并且等待线程中的写加锁线程比读加锁线程优先级高。

总结一下:

读共享,写独享;写必读优先级高。

0 人点赞