当前位置: 首页 > news >正文

网站开发发现趋势做网站的绿色背景图

网站开发发现趋势,做网站的绿色背景图,做网站如何保证询盘数量,服务器一年多少钱文章目录 【C专题】读写锁(Reader-Writer Lock)原理与实现方式(含C11/20实践)一、读写锁核心概念1. **什么是读写锁?**2. **读写锁 vs 互斥锁** 二、C中的读写锁实现方式 方案一:POSIX 读写锁(p…

文章目录

      • 【C++专题】读写锁(Reader-Writer Lock)原理与实现方式(含C++11/20实践)
        • 一、读写锁核心概念
          • 1. **什么是读写锁?**
          • 2. **读写锁 vs 互斥锁**
        • 二、C++中的读写锁实现方式
      • 方案一:POSIX 读写锁(pthread_rwlock)
          • 1. **关键接口**
          • 2. **使用示例:缓存读取与更新**
          • 3. **注意事项**
      • 方案二:C++20 共享互斥锁(std::shared_mutex)
          • 1. **核心类**
          • 2. **使用示例:线程安全的计数器**
          • 3. **优势**
      • 方案三:自定义读写锁(基于互斥量与条件变量)
          • 1. **实现原理**
          • 2. **代码实现(简化版)**
          • 3. **关键点**
        • 三、读写锁的性能与陷阱
          • 1. **性能对比**
          • 2. **常见陷阱**
        • 四、最佳实践建议
        • 五、总结

【C++专题】读写锁(Reader-Writer Lock)原理与实现方式(含C++11/20实践)

一、读写锁核心概念
1. 什么是读写锁?

读写锁是一种同步机制,用于控制多个线程对共享资源的访问,其核心特性:

  • 读锁(共享锁):允许多个线程同时获取,适用于只读操作(如读取配置文件、缓存查询)。
  • 写锁(排他锁):仅允许单个线程获取,适用于写操作(如修改数据、更新缓存),此时其他线程(包括读线程)均被阻塞。

适用场景:读多写少的场景(如数据库缓存、日志系统),相比普通互斥锁(Mutex)能显著提升并发性。

2. 读写锁 vs 互斥锁
维度互斥锁(Mutex)读写锁(Reader-Writer Lock)
读操作并发同一时间仅1线程访问允许多线程同时读
写操作开销低(简单加锁)高(需协调读/写线程)
典型场景读写均衡或写多读少读多写少(如配置中心、缓存)
二、C++中的读写锁实现方式

方案一:POSIX 读写锁(pthread_rwlock)

适用范围:Linux/macOS等UNIX-like系统,C++11之前的主流方案。

1. 关键接口
#include <pthread.h>// 初始化读写锁
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);// 加读锁(阻塞式)
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
// 尝试加读锁(非阻塞,成功返回0,失败返回EBUSY)
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);// 加写锁(阻塞式)
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
// 尝试加写锁(非阻塞)
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);// 解锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);// 销毁锁
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
2. 使用示例:缓存读取与更新
#include <iostream>
#include <pthread.h>
#include <vector>
#include <thread>pthread_rwlock_t rwlock;
std::vector<int> cache;// 读线程:获取读锁,读取缓存
void read_cache(int id) {pthread_rwlock_rdlock(&rwlock);std::cout << "Thread " << id << " reading: ";for (auto val : cache) {std::cout << val << " ";}std::cout << std::endl;pthread_rwlock_unlock(&rwlock);
}// 写线程:获取写锁,更新缓存
void update_cache(int id, std::vector<int> new_data) {pthread_rwlock_wrlock(&rwlock);cache = new_data;std::cout << "Thread " << id << " updated cache." << std::endl;pthread_rwlock_unlock(&rwlock);
}int main() {pthread_rwlock_init(&rwlock, nullptr);cache = {1, 2, 3};// 启动3个读线程std::thread readers[3];for (int i = 0; i < 3; ++i) {readers[i] = std::thread(read_cache, i);}// 启动1个写线程(会等待读线程释放锁)std::thread writer(update_cache, 4, {4, 5, 6});// 等待所有线程结束for (auto& th : readers) th.join();writer.join();pthread_rwlock_destroy(&rwlock);return 0;
}
3. 注意事项
  • 初始化与销毁:需调用pthread_rwlock_initpthread_rwlock_destroy,避免内存泄漏。
  • 线程安全:写锁具有更高优先级,避免读线程饥饿(某些实现支持“写优先”策略)。

方案二:C++20 共享互斥锁(std::shared_mutex)

适用范围:C++20及以上标准,跨平台(Windows/Linux/macOS)。

1. 核心类
  • std::shared_mutex:底层实现读写锁语义。
  • std::shared_lock:用于获取读锁(共享锁)。
  • std::unique_lock:用于获取写锁(排他锁)。
2. 使用示例:线程安全的计数器
#include <iostream>
#include <shared_mutex>
#include <thread>
#include <vector>std::shared_mutex rw_mutex;
int counter = 0;// 读操作:统计计数器值
void read_counter(int id) {std::shared_lock<std::shared_mutex> lock(rw_mutex); // 自动获取读锁std::cout << "Thread " << id << ": Counter = " << counter << std::endl;
}// 写操作:增加计数器值
void increment_counter(int id, int times) {std::unique_lock<std::shared_mutex> lock(rw_mutex); // 自动获取写锁for (int i = 0; i < times; ++i) {counter++;}std::cout << "Thread " << id << " updated counter to " << counter << std::endl;
}int main() {std::vector<std::thread> threads;// 启动5个读线程for (int i = 0; i < 5; ++i) {threads.emplace_back(read_counter, i);}// 启动2个写线程for (int i = 5; i < 7; ++i) {threads.emplace_back(increment_counter, i, 100);}for (auto& th : threads) th.join();return 0;
}
3. 优势
  • RAII风格:通过std::shared_lockstd::unique_lock自动管理锁的生命周期,避免忘记解锁。
  • 跨平台兼容:无需依赖POSIX接口,可在Windows(如Visual Studio 2019+)和UNIX系统上编译。

方案三:自定义读写锁(基于互斥量与条件变量)

适用场景:需要理解底层原理,或在不支持C++20的环境中模拟读写锁。

1. 实现原理
  • 读计数器:记录当前获取读锁的线程数,无写锁时允许多线程读。
  • 写锁标志:表示是否有线程持有写锁,写锁获取时阻塞所有读线程。
  • 条件变量:用于写线程等待读线程释放锁,或读线程等待写锁释放。
2. 代码实现(简化版)
#include <mutex>
#include <condition_variable>class ReadWriteLock {
private:std::mutex mtx;std::condition_variable read_cv, write_cv;int reader_count = 0;bool writer_active = false;public:// 获取读锁void lock_read() {std::unique_lock<std::mutex> lock(mtx);// 等待写锁释放read_cv.wait(lock, [this]() { return !writer_active; });reader_count++;}// 释放读锁void unlock_read() {std::unique_lock<std::mutex> lock(mtx);reader_count--;if (reader_count == 0) {write_cv.notify_one(); // 唤醒等待的写线程}}// 获取写锁void lock_write() {std::unique_lock<std::mutex> lock(mtx);// 等待所有读线程释放且无写锁write_cv.wait(lock, [this]() { return reader_count == 0 && !writer_active; });writer_active = true;}// 释放写锁void unlock_write() {std::unique_lock<std::mutex> lock(mtx);writer_active = false;read_cv.notify_all(); // 唤醒所有读线程write_cv.notify_one(); // 唤醒可能等待的写线程}
};
3. 关键点
  • 读锁加锁:通过条件变量等待写锁释放,允许多线程同时持有读锁(通过reader_count计数)。
  • 写锁加锁:必须等待所有读锁释放(reader_count==0)且无其他写锁。
  • 优先级策略:此实现为“读优先”,写线程可能饥饿,可通过增加写等待标志优化为“写优先”。
三、读写锁的性能与陷阱
1. 性能对比
操作类型POSIX读写锁std::shared_mutex自定义读写锁(读优先)
读锁加锁耗时
写锁加锁耗时
适用场景系统级开发现代C++应用学习/定制化需求
2. 常见陷阱
  • 死锁:读线程持有读锁时尝试获取写锁,或写线程同时获取多个锁(需避免嵌套加锁)。
  • 饥饿:读线程过多导致写线程长期无法获取锁(可通过“写优先”策略缓解)。
  • 错误解锁:读锁释放时未正确更新计数器,或写锁释放时未通知等待线程。
四、最佳实践建议
  1. 优先使用C++20标准库std::shared_mutexstd::shared_lock提供简洁、安全的读写锁实现,推荐用于新项目。
  2. 明确锁作用域:使用RAII风格的lock_guardunique_lock,避免锁的作用域泄漏。
  3. 性能测试:在高并发场景下,通过基准测试(如Google Benchmark)比较读写锁与无锁编程(如原子操作)的性能差异。
  4. 文档与注释:在代码中注明锁的类型(读锁/写锁)和保护的共享资源,提升可维护性。
五、总结

读写锁是多线程编程中提升读性能的关键工具,其核心在于分离读/写操作的并发策略:

  • POSIX读写锁:适用于UNIX系统的高性能场景,但需手动管理锁生命周期。
  • C++20共享互斥锁:跨平台、安全、简洁,推荐现代C++项目使用。
  • 自定义实现:帮助理解底层原理,但需谨慎处理线程安全和性能问题。

合理使用读写锁能显著优化读多写少场景的并发性,但需注意避免死锁和饥饿问题,结合具体业务场景选择最优方案。

参考资料

  • C++标准文档:std::shared_mutex
  • POSIX文档:pthread_rwlock
  • 《C++ Concurrency in Action》
http://www.dtcms.com/a/566342.html

相关文章:

  • ArkTS技术深度解析与扩展应用实践
  • Zermelo–Fraenkel 公理集合论(ZF)
  • 网站 做 app开发工具班级网站建设的范围
  • 静态页优秀网站老板电器分销系统
  • JavaScript 数组清空的3种方法
  • 在哪个网站做淘宝水印秦皇岛网站排名公司
  • 车载诊断框架 --- 诊断企业规范怎么定义 Service 10?
  • 陕西网站建设哪家好网站制作完成后
  • 网站代码上传后无法打开富库网站建设
  • 深圳设计功能网站wordpress权限acl
  • 建设部网站 规范下载2021最旺公司名字
  • 网站收录有什么用网站建设与维护教学视频教程
  • 做少儿培训网站的公司中国建设银行注册网站用户名怎么填
  • 唐山网站主页制作邢台123生活信息网
  • 爱美刻在线制作网站4399游戏网页版入口
  • 政务网站集约化建设有哪些做的好的小众网站
  • 济南seo网站关键词优化排名wordpress企业产品列表
  • 【cursor】常用使用技巧篇
  • 河北保定建设集团招聘信息网站百度是什么网站
  • 华为OD机试双机位A卷 - IPv4地址转换成整数 (C++ Python JAVA JS GO)
  • 个人网站不备案可以吗网站域名注册商标有什么好处
  • CSS实现跑马灯效果-案例
  • 1元云购网站怎样建设php做网站登陆验证
  • 织梦 营销型网站网络运维工程师有前途吗
  • 11. Qt 绘图-基础
  • 【LeetCode】组合问题——1863.找出所有子集的异或总和再求和(回溯)
  • 网站安全维护公司浙江省住房和城乡建设部网站
  • 成都哪些公司做网站好用网址进入的游戏
  • sparkSQL读取数据的方式
  • 国内免费建站网站wordpress教程视频教程