首页 > 解决方案 > 关于std::shared_mutex的问题:threads/reader can't read variable同时

问题描述

这是我的代码

#include <iostream>
#include <mutex>
#include <shared_mutex>
#include <thread>
#include <windows.h>

using namespace std;
class Counter {
public:
    Counter() : value_(0) {
    }

    // Multiple threads/readers can read the counter's value at the same time.
    std::size_t Get() const {
        std::shared_lock<std::shared_mutex> lock(mutex_);
        std::cout << std::this_thread::get_id() << ' ' << value_ << std::endl;
        Sleep(1000);
        return value_;
    }

    // Only one thread/writer can increment/write the counter's value.
    void Increase() {
        // You can also use lock_guard here.
        std::unique_lock<std::shared_mutex> lock(mutex_);
        value_++;
        lock.unlock();
    }

private:
    mutable std::shared_mutex mutex_;
    std::size_t value_;
};



void Worker(Counter& counter) {
    counter.Get();
    counter.Increase();
    counter.Get();
}

#include <vector>
int main() {
    Counter counter;
    std::vector<std::thread> v;
    for(int i(0);i<10;i++){v.emplace_back(&Worker, std::ref(counter));}
    for (std::thread& t : v) t.join();
    return 0;
}

结果是这样的:</p>

12188457610048 10196 06744
3692  0011812 8392 6912  00
10392 00
0

0
0



6744 1
3692 2
11812 3
10048 4
4576 5
10392 6
8392 7
10196 8
12188 9
6912 10

这很奇怪:第一次运行“counter.Get()”时,所有读取线程都在同时读取。但是第二次,在使用“counter.Increase”后再次运行“counter.Get()” ()",所有的读者线程只需等待 1 秒即可得到答案。这是为什么?有什么办法可以解决吗?</p>

标签: c++stdmutexshared

解决方案


因为链接

如果一个线程已经获得了共享锁(通过lock_shared,try_lock_shared),其他线程不能获得排他锁,但可以获得共享锁。

首先Get为所有工作人员同时运行,因为 onlyshared_lock是获取的。但是,Increase操作需要排他锁。现在,从操作中释放排他锁后,Increase您立即在第二次操作中获取共享锁Get,这导致所有尚未调用的线程Increase等待 1 秒直到Get释放锁。


推荐阅读