C++多读者单写者互斥锁场景写者优先避免饥饿方案问询
实现方案
核心逻辑用原子标记+读写锁就能实现,不需要条件变量,逻辑简单性能高,完全匹配你的需求:
- 写线程几乎无额外调度开销,大部分时间处于休眠状态
- 读线程主动给写线程让行,保证写优先级高于读
- 跨平台兼容,不受POSIX/Windows原生调度策略影响
用到的核心组件
std::atomic<bool>原子类型做写等待标记,无锁操作性能高,保证多线程下的变量可见性std::shared_mutex标准读写锁,读线程拿共享锁,写线程拿独占锁
完整实现代码
#include <shared_mutex> #include <atomic> #include <vector> #include <thread> #include <chrono> // 公共访问的vector数据 std::vector<int> data; // 读写锁 std::shared_mutex rw_mutex; // 写线程等待标记:true表示写线程准备要拿锁了 std::atomic<bool> writer_waiting = false; // 写线程实现 void writer_routine() { while (true) { // 模拟极低频次执行,长时间休眠 std::this_thread::sleep_for(std::chrono::minutes(10)); // 先标记写线程要工作了,通知所有读线程让行 writer_waiting.store(true, std::memory_order_release); // 拿独占写锁,此时只会等已经持有读锁的线程释放,不会被新的读线程抢锁 std::unique_lock<std::shared_mutex> write_lock(rw_mutex); // 拿到锁后清除等待标记 writer_waiting.store(false, std::memory_order_release); // 执行写操作逻辑,比如插入、更新vector data.push_back(rand()); } } // 读线程实现 void reader_routine() { while (true) { // 检查有没有写线程在等待,有的话主动让行,直到写线程完成操作 // 因为写频次极低,这里的等待开销几乎可以忽略 while (writer_waiting.load(std::memory_order_acquire)) { // 加1微秒休眠减少CPU占用,也可以用std::this_thread::yield()主动让出时间片 std::this_thread::sleep_for(std::chrono::microseconds(1)); } // 无写等待时拿共享读锁 std::shared_lock<std::shared_mutex> read_lock(rw_mutex); // 执行读操作逻辑,比如遍历、读取vector元素 if (!data.empty()) { int current_val = data.back(); // 此处添加读数据的业务逻辑 } } }
方案说明
- 读线程在抢读锁前会先检查写等待标记,只要有写线程在等待,就不会抢读锁,保证写线程能快速拿到独占锁
- 即使出现极个别读线程在「检查标记」和「拿锁」的间隙,写线程刚好设置了等待标记的情况,也只会让写线程多等最多几个已持锁读线程的执行时间,不会出现写线程被长期阻塞的问题
- 写线程不需要维护任何读线程的调度逻辑,写完释放锁就完事,完全符合你要的低调度开销需求
内容的提问来源于stack exchange,提问作者BobtheMagicMoose
相关产品推荐
相关产品推荐

