这是我的代码
#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;
}
结果是这样的:
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之后,再次运行” counter.Get()“ .Increase()“,所有阅读器线程只需等待1秒钟即可得到答案。为什么呢?有什么办法可以解决?
作家释放锁定后,哪个线程使用互斥锁的机会不相等,因此在您的情况下,同一线程很可能会再次使用它。当读者使用互斥量时,作家不断等待。
这被称为不公平。相比之下,fair互斥锁会给其他线程一些机会。
C ++标准未定义C ++互斥对象是公平还是不公平。
通常,它们是不公平的,因为不公平的互斥通常会提高性能。
因为link
如果一个线程已经获取了共享锁(通过lock_shared,try_lock_shared),则其他线程都无法获取排他锁,但是可以获取共享锁。
First Get
同时为所有工作程序运行,因为仅获取shared_lock
。但是,Increase
操作需要互斥锁定。现在,从Increase
操作中释放排他锁后,您立即在第二个Get
操作中获得了共享锁,这将导致所有尚未调用Increase
的线程都等待1秒,直到Get
释放锁为止。