c++ - 关于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>
解决方案
因为链接
如果一个线程已经获得了共享锁(通过lock_shared,try_lock_shared),其他线程不能获得排他锁,但可以获得共享锁。
首先Get
为所有工作人员同时运行,因为 onlyshared_lock
是获取的。但是,Increase
操作需要排他锁。现在,从操作中释放排他锁后,Increase
您立即在第二次操作中获取共享锁Get
,这导致所有尚未调用的线程Increase
等待 1 秒直到Get
释放锁。
推荐阅读
- python - 多个类和 IndexError:列出超出范围错误的索引
- javascript - 另一个 Angular 项目中的 Angular 项目:未捕获(承诺中):TypeError: ne is not a function
- printf - printf 不会在屏幕上返回任何内容
- python - 尝试使用 numpy.gradient 查找数组的梯度时出现错误
- html - 如何管理表格中的边框间距?
- php - XERO PHP API 将文件附加到发票 - 发送时不包含文件
- point - 无法使用 Geopandas / Shapely 从浮点数据创建几何点
- python - 使用 bootstrap4 轮播的 django 网站中的滑块
- c# - 带有 IEWebDriver 的 Selenium 无法识别输入的输入值
- plotly-dash - 是否可以在单个独立的 html 文件中导出 Plotly Dash 应用程序?