Linux线程---线程同步互斥:读写锁

读写锁与互斥量的功能类似,对临界区的共享资源进行保护!互斥量一次只让一个线程进入临界区,读写锁比它有更高的并行性。读写锁有以下特点:

1.如果一个线程用读锁锁定了临界区,那么其他线程也可以用读锁来进入临界区,这样就可以多个线程并行操作。但这个时候,如果再进行写锁加锁就会发生阻塞,写锁请求阻塞后,后面如果继续有读锁来请求,这些后来的读锁都会被阻塞!这样避免了读锁长期占用资源,防止写锁饥饿!

2.如果一个线程用写锁锁住了临界区,那么其他线程不管是读锁还是写锁都会发生阻塞!

示例
创建4个线程,2个线程读锁,2个线程写锁,观察4个线程进入临界区的顺序

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

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int count = 0;

void reader(void *arg)
{
    char *name = (char*)arg;

    while(1)
    {
        // 获取读写锁中的读锁
        // int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock );
        // 如果写入器未持有读锁,并且没有任何写入器基于该锁阻塞,则调用线程会获取读锁。
        // 如果写入器未持有读锁,但有多个写入器正在等待该锁时,调用线程是否能获取该锁是不确定的。
        // 如果某个写入器持有读锁,则调用线程无法获取该锁。
        // 如果调用线程未获取读锁,则它将阻塞。
        // 调用线程必须获取该锁之后,才能从pthread_rwlock_rdlock()返回。
        // 如果在进行调用时,调用线程持有rwlock中的写锁,则结果是不确定的。
        // 为避免写入器资源匮乏,允许在多个实现中使写入器的优先级高于读取器。
        pthread_rwlock_rdlock(&rwlock);

        printf("read_%s enters: %d\n", name, count);
        usleep(1000);
        printf("read_%s leave: %d\n", name, count);

        // 解除锁定读写锁
        pthread_rwlock_unlock(&rwlock);

        usleep(1000);
    }
}

void writer(void *arg)
{
    char *name = (char*)arg;

    while(1)
    {
        // 获取读写锁中的写锁
        // int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock );
        // 如果没有其他读取器线程或写入器线程持有读写锁rwlock,则调用线程将获取写锁
        // 否则,调用线程将阻塞。
        // 调用线程必须获取该锁之后,才能从pthread_rwlock_wrlock()调用返回
        // 如果在进行调用时,调用线程持有读写锁(读锁或写锁),则结果是不确定的
        // 为避免写入器资源匮乏,允许在多个实现中使写入器的优先级高于读取器
        pthread_rwlock_wrlock(&rwlock);

        count++;
        printf("write_%s enters: %d\n", name, count);
        usleep(1000);
        printf("write_%s leave: %d\n", name, count);

        // 解除锁定读写锁
        pthread_rwlock_unlock(&rwlock);

        usleep(2000);
    }
}

int main()
{   
    pthread_t r, r1, w, w1;

    pthread_create(&r, NULL, (void*)reader, (void*)"1");
    pthread_create(&r1, NULL, (void*)reader, (void*)"2");
    pthread_create(&w, NULL, (void*)writer, (void*)"1");
    pthread_create(&w1, NULL, (void*)writer, (void*)"2");

    pthread_join(r, NULL);
    pthread_join(r1, NULL);
    pthread_join(w,NULL);
    pthread_join(w1, NULL);

    // 销毁读写锁
    pthread_rwlock_destroy(&rwlock);

    return 0;
}

这里写图片描述

参考
https://www.cnblogs.com/yuuyuu/p/5143881.html
多线程编程指南

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值