详细介绍读写锁

读写锁(Read-Write Lock)是一种优化型的同步机制 ,专门针对读多写少的场景设计,它允许多个读线程同时访问共享资源,但写线程会独占资源,从而在保证数据一致性的前提下提升并发效率。

一、核心特点

读写锁遵循"读共享、写独占"的规则:

  • 读模式加锁:多个读线程可以同时持有读锁;
  • 写模式加锁:写线程会阻塞所有读线程和其他写线程,独占资源;
  • 读写冲突:写线程会等待所有读线程释放读锁,读线程会等待写线程释放写锁。
二、适用场景

适用于读操作远多于写操作的场景(如缓存、配置文件读取),相比普通互斥锁,能大幅提升读操作的并发性能。

三、POSIX读写锁(C语言)的核心函数

以 pthread_rwlock_t 为例:

函数 功能
pthread_rwlock_init 初始化读写锁,参数指定锁的属性(如进程间共享)
pthread_rwlock_rdlock 以读模式 加锁: - 无写锁时,直接获取; - 有写锁时,阻塞等待写锁释放
pthread_rwlock_wrlock 以写模式 加锁: - 无读锁和写锁时,直接获取; - 有读锁/写锁时,阻塞等待所有锁释放
pthread_rwlock_tryrdlock 尝试以读模式加锁: - 成功获取返回0; - 失败直接返回错误(不阻塞)
pthread_rwlock_trywrlock 尝试以写模式加锁: - 成功获取返回0; - 失败直接返回错误(不阻塞)
pthread_rwlock_unlock 释放锁: - 读锁释放后,若有写线程等待,会唤醒写线程; - 写锁释放后,会唤醒所有等待的读/写线程
pthread_rwlock_destroy 销毁读写锁,释放资源
四、典型使用示例(读多写少场景)
c 复制代码
  
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

pthread_rwlock_t rwlock;  // 读写锁
int shared_data = 0;      // 共享资源

// 读线程:同时多个线程可读取
void* reader(void* arg) {
    while (1) {
        pthread_rwlock_rdlock(&rwlock);
        printf("读线程%d:shared_data = %d\n", *(int*)arg, shared_data);
        pthread_rwlock_unlock(&rwlock);
        sleep(1);  // 模拟读操作耗时
    }
    return NULL;
}

// 写线程:独占资源
void* writer(void* arg) {
    while (1) {
        pthread_rwlock_wrlock(&rwlock);
        shared_data++;
        printf("写线程:shared_data 更新为 %d\n", shared_data);
        pthread_rwlock_unlock(&rwlock);
        sleep(3);  // 模拟写操作耗时(写频率低于读)
    }
    return NULL;
}

int main() {
    pthread_rwlock_init(&rwlock, NULL);

    pthread_t r1, r2, w1;
    int r1_id = 1, r2_id = 2;
    pthread_create(&r1, NULL, reader, &r1_id);
    pthread_create(&r2, NULL, reader, &r2_id);
    pthread_create(&w1, NULL, writer, NULL);

    pthread_join(r1, NULL);
    pthread_join(r2, NULL);
    pthread_join(w1, NULL);

    pthread_rwlock_destroy(&rwlock);
    return 0;
}
五、与普通互斥锁的对比
维度 普通互斥锁 读写锁
并发性能 所有线程串行访问,读多写少时效率低 读线程并行访问,读多写少时效率高
适用场景 读写频率均衡或写多 读多写少
锁冲突规则 所有线程互斥 读-读共享,读-写互斥,写-写互斥
六、注意事项
  1. 写饥饿问题:若读线程持续持有读锁,写线程可能长期等待("写饥饿")。部分实现会优先唤醒写线程,避免此问题;
  2. 锁升级/降级:多数读写锁不支持"读锁升级为写锁"(易死锁),但支持"写锁降级为读锁"。
相关推荐
汉克老师32 分钟前
GESP2026年9月认证C++八级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
郝学胜_神的一滴2 小时前
C++ Templates 06:搞懂模板代码的三种组织方式
c++·visual studio
C++ 老炮儿的技术栈2 小时前
sizeof操作符
c语言·c++·人工智能·mfc·c
沫璃染墨2 小时前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
wuminyu2 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
code2cat3 小时前
Java进阶篇之AtomicMarkableReference:引用还在,标记已经改变
java·开发语言·cas·并发编程·逻辑删除
CappuccinoRose3 小时前
FormData数据处理
开发语言·前端·javascript·表单数据
Zguigo3 小时前
【CUDA8】第一个CUDA C++ Kernel --vector add
java·开发语言·c++
-Marks-3 小时前
【C++编程】STL容器(二)--- vector底层模拟实现(常用接口实现 | 扩容机制 | 深浅拷贝 | 迭代器失效)
开发语言·c++·vector·内存管理·迭代器失效·vector底层模拟实现
Shadow(⊙o⊙)4 小时前
C++11并发支持库
开发语言·c++