简体   繁体   English

关于std::shared_mutex的问题:threads/reader can't read variable同时

[英]question about std::shared_mutex: threads/reader can‘t read variable at the same time

here is my code这是我的代码

#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;
}

And the result is like this:结果是这样的:

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

It is pretty weird:at the first time I run "counter.Get()",all the reader thread are reading at the same time.But the second time,run "counter.Get()" again after using "counter.Increase()",all the reader thread just have to wait 1 sec to get the answer.Why is that?Is there anything I can do to fix that?这很奇怪:第一次运行“counter.Get()”时,所有读取线程都在同时读取。但是第二次,使用“counter.Increase”后再次运行“counter.Get()” ()",所有读者线程只需要等待 1 秒即可得到答案。这是为什么?有什么办法可以解决吗?

Because link因为链接

If one thread has acquired the shared lock (through lock_shared, try_lock_shared), no other thread can acquire the exclusive lock, but can acquire the shared lock.如果一个线程已经获得了共享锁(通过lock_shared,try_lock_shared),其他线程不能获得排他锁,但可以获得共享锁。

First Get runs concurrently for all workers, because only shared_lock is acquired. First Get对所有工作人员同时运行,因为只获取shared_lock However, Increase operation requires exclusive lock.但是, Increase操作需要排他锁。 Now, after releasing exclusive lock from Increase operation you immediately acquire shared lock in second Get operation, which causes all threads that did not call Increase yet to wait 1sec until Get releases the lock.现在,从Increase操作释放独占锁后,您立即在第二个Get操作中获取共享锁,这导致所有尚未调用Increase的线程等待1 秒,直到Get释放锁。

After a writer releases lock, the chances which thread takes the mutex are not equal, so the same thread is likely to take it again in your case.在作家释放锁定后,哪个线程获取互斥锁的机会不相等,因此在您的情况下,同一个线程可能会再次获取它。 As reader takes mutex, writers keep waiting.当读者使用互斥锁时,作者一直在等待。

This is called unfair .这叫不公平 In contrast, fair mutex would have given some chance to other threads.相反,公平互斥体会给其他线程一些机会。

C++ Standard does not define whether C++ mutexes are fair or unfair. C++ 标准没有定义 C++ 互斥体是公平的还是不公平的。

Typically they are unfair, as unfair mutexes are usually better for performance.通常它们是不公平的,因为不公平的互斥锁通常对性能更好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 std::shared_mutex 不与执行 lock_shared() 的线程一起缩放 - std::shared_mutex not scaling with threads doing lock_shared() 关于跨多个线程的shared_mutex和shared_ptr - About shared_mutex and shared_ptr across multiple threads 尝试std :: lock [_unique] std :: shared_mutex的线程是否可以被调用std :: lock_shared的线程饿死? - Can thread trying to std::lock[_unique] an std::shared_mutex be starved by threads calling std::lock_shared? 带有std :: shared_lock的std :: shared_mutex是读者还是作家更喜欢? - std::shared_mutex with std::shared_lock is reader or writer preferring? scoped_lock可以在读模式下锁定shared_mutex吗? - Can scoped_lock lock a shared_mutex in read mode? 错误:使用ReaderLock = std :: shared_lock的&#39;shared_mutex&#39;不是&#39;std&#39;的成员 <std::shared_mutex> ; - error: ‘shared_mutex’ is not a member of ‘std’ using ReaderLock = std::shared_lock<std::shared_mutex>; std :: lock()是否等同于boost :: shared_mutex? - std::lock() equivalent for boost::shared_mutex? std :: mutex和std :: shared_mutex之间的区别 - difference between std::mutex and std::shared_mutex 我可以在 std::shared_mutex 上使用 std::shared_lock 更改数据吗? - Can I change data with a std::shared_lock on a std::shared_mutex? Boost-shared_mutex必须是同一实例吗? - Boost - shared_mutex has to be same instance?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM