线程同步(二):读写锁

一、读写锁

读写锁实际是一种特殊的自旋锁,它把对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作。

1.特性

  1. 锁只有一把,“读锁”、“写锁”是加锁的两种方式。“读锁”是读模式下加锁状态,“写锁”是写模式下加锁状态。
  2. 一个读写锁同时只能有一个写者,可以有多个读者,但读者和写者不能同时访问(读共享,写独占)。
  3. 写锁优先级高。

2.具体情景下读者写者优先级分析

现在有两个写者w1,w2;三个读者r1,r2,r3;

  • [ 1 ]r1,r2,r3同时访问,均能获取锁并读取数据;
  • [ 2 ]r1,w1同时竞争,w1能获取锁,进行写操作,r1阻塞;
  • [ 3 ]r1加锁成功,w1,r2,w2同时请求访问,则三者均会阻塞,在r1释放锁时,w1,w2会竞争抢夺,r2优先级排在最后;
  • [ 4 ]r1加锁成功,r2,r3同时请求访问,则均能加锁成功,进行读操作;
  • [ 5 ]w1加锁成功,则不论后续是谁请求访问,均会阻塞。

3.读写锁相关操作

pthread_rwlock_t  rwlock;				//定义

pthread_rwlock_init(&rwlock, NULL);		//初始化

pthread_rwlock_rdlock(&rwlock);			//读模式加锁,失败时阻塞	

pthread_rwlock_tryrdlock(&rwlock);		//读模式尝试加锁,失败时立即返回

pthread_rwlock_wrlock(&rwlock);			//写模式加锁,失败时阻塞	

pthread_rwlock_wrlock(&rwlock);			//写模式尝试加锁,失败时立即返回

pthread_rwlock_unlock(&rwlock);			//解锁			

pthread_rwlock_destroy(&rwlock);		//销毁锁

二、Demo

3个线程不定时 “写” 全局资源,5个线程不定时 “读” 同一全局资源

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>

int counter;                          //全局资源
pthread_rwlock_t rwlock;

void *th_write(void *arg)
{
    int t;
    int i = (int)arg;

    while (1) {
        t = counter;                    // 保存写之前的值
        usleep(1000);

        pthread_rwlock_wrlock(&rwlock);
        printf("=======write %d: %lu: counter=%d ++counter=%d\n", i, pthread_self(), t, ++counter);
        pthread_rwlock_unlock(&rwlock);

        usleep(9000);               // 给 r 锁提供机会
    }
    return NULL;
}

void *th_read(void *arg)
{
    int i = (int)arg;

    while (1) {
        pthread_rwlock_rdlock(&rwlock);
        printf("----------------------------read %d: %lu: %d\n", i, pthread_self(), counter);
        pthread_rwlock_unlock(&rwlock);

        usleep(2000);                // 给写锁提供机会
    }
    return NULL;
}

int main(void)
{
    int i;
    pthread_t tid[8];

    pthread_rwlock_init(&rwlock, NULL);

    for (i = 0; i < 3; i++)//创建3个写者线程
        pthread_create(&tid[i], NULL, th_write, (void *)i);

    for (i = 0; i < 5; i++)//创建5个读者线程
        pthread_create(&tid[i+3], NULL, th_read, (void *)i);

    for (i = 0; i < 8; i++)//回收线程资源
        pthread_join(tid[i], NULL);

    pthread_rwlock_destroy(&rwlock);            //释放读写琐

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值