简体   繁体   English

什么时候使用unique_lock与shared_mutex?

[英]At what point to use unique_lock with shared_mutex?

Typically, when using a "normal" mutex, you would use it as in remove1() . 通常,在使用“普通”互斥锁时,您可以像在remove1()一样使用它。 However, now with shared_lock and unique_lock , should you use a shared lock first and the unique lock only when necessary? 但是,现在使用shared_lockunique_lock ,您是否应首先使用共享锁,并且仅在必要时使用唯一锁? Note that remove() may not need to unique_lock when the model does not exist. 请注意,当模型不存在时, remove()可能不需要unique_lock

void remove1(int id) {
    std::unique_lock<std::shared_mutex> lock(mutex_);
    for (auto it = models_.begin(); it != models_.end(); ++it)
        if ((*it)->getId() == id)
        {
            it = models_.erase(it);
            return;
        {
}

void remove2(int id) {
    std::shared_lock<std::shared_mutex> sharedLock(mutex_);
    for (auto it = models_.begin(); it != models_.end(); ++it)
        if ((*it)->getId() == id)
        {
            sharedLock.unlock();
            std::unique_lock<std::shared_mutex> uniqueLock(mutex_);
            models_.erase(it);
            return;
        }
}
 sharedLock.unlock(); std::unique_lock<std::shared_mutex> uniqueLock(mutex_); 

Just because two operations are individually atomic does not mean that one followed by the other represents an atomic sequence. 仅仅因为两个操作是单独原子的并不意味着一个跟随另一个代表原子序列。 Once you give up a lock, you give it up . 一旦你放弃锁定,你就放弃了 If that mutex guards access to the container, there's nothing preventing the iterator you have from being invalidated. 如果该互斥锁保护对容器的访问,则没有任何东西阻止您使迭代器失效。

What you're trying to do is have the inner unique_lock atomically upgrade the outer shared_lock in exclusive mode. 您要做的是让内部unique_lock以独占模式原子升级外部shared_lock That can't be done in C++17 at all. 这完全不能在C ++ 17中完成。

And of course, you never re-lock the shared_lock before you leave the if block, so after erasing one element, you're in trouble. 当然,在离开if块之前,你永远不会重新锁定shared_lock ,因此在擦除一个元素之后,你就遇到了麻烦。

And that ignores the fact that whenever you erase an element from either of your loops, you'll skip the next one. 而且忽略了这样一个事实:无论何时从你的任何一个循环中erase一个元素,你都会跳过下一个循环。 The iterator returned by erase points to the next element, and your ++it in the loop header will skip it. 迭代器由erase点返回到下一个元素,而你在循环头中的++it跳过它。 This is true of both functions. 两种功能都是如此。

But in any case, the overall purpose of shared_mutex is to permit multiple readers but only one modifier. 但无论如何, shared_mutex的总体目的是允许多个读者但只允许一个修饰符。 Your entire operation is really a modification operation. 您的整个操作实际上是一个修改操作。 It may be conditionally modifying, but atomically it is a modification operation. 它可能是有条件的修改,但在原子上它是一个修改操作。 What you want is for everyone to either see the list as it was before the operation or for everyone to see the list as it was after all matching elements are erased. 你想要的是让每个人都能看到在操作之前的列表,或者让每个人都看到列表,因为删除了所有匹配的元素之后 Nobody should ever see the list while you're modifying it. 在修改列表时,没有人会看到列表。

So it should use exclusive access. 所以它应该使用独占访问。

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

相关问题 何时使用C ++ 11互斥锁,锁,unique_lock,shared_lock等 - When to use C++11 mutex, lock, unique_lock, shared_lock, etc shared_mutex锁定顺序 - shared_mutex lock ordering 在`unique_lock`,`scoped_lock`和`lock_guard`中指定的mutex_type的用例是什么? - What is the use case for mutex_type specified in `unique_lock`, `scoped_lock` and `lock_guard`? 当单个线程获取同一个互斥锁的 2 个 unique_lock 时,unique_lock 是什么意思? - what does unique_lock mean when a single thread acquire 2 unique_lock of the same mutex? mutex.lock与unique_lock - mutex.lock vs unique_lock std :: lock()是否等同于boost :: shared_mutex? - std::lock() equivalent for boost::shared_mutex? unique_lock 不同线程中的相同互斥锁 - unique_lock same mutex in different thread 如何解锁boost :: upgrade_to_unique_lock(由boost :: shared_mutex制作)? - How to unlock boost::upgrade_to_unique_lock (made from boost::shared_mutex)? 错误:使用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 [_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?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM