c++ 我可以在同一个线程中的shared_lock和unique_lock之间共享互斥锁吗?

xeufq47z  于 2023-03-25  发布在  其他
关注(0)|答案(2)|浏览(151)

考虑以下函数:

std::shared_mutex mutex;
 
 void foo() {
     std::shared_lock readLock{ mutex };
     // ...
     // read-only part of the function
     // ...
     {
         std::unique_lock lock{ mutex, std::adopt_lock }
         // ...
         // read/write part
         // ...
     }
     // ... some other read part ...
 }

最初,函数只有一个,std::unique_lock用于所有部分。它工作正常,但作为优化的一部分,它将一些部分 Package 为std::shared_lock。对我来说,它看起来完全合法,但在玩了一圈之后,结果发现一些死锁开始出现(不一定在函数中,但很明显,这个变化是问题的根本原因)
有谁能详细说明一下这种方法是否定义良好,以及它究竟为什么会出现死锁问题?

e5njpo68

e5njpo681#

看起来你想把共享锁升级为唯一锁。你做错了-std::shared_mutex不是递归的,不能升级。先释放共享锁,然后正常地独占锁。

std::shared_mutex mutex;

void foo()
{
    {
        std::shared_lock readLock{ mutex };
        // ...
        // read-only part of the function
        // ...
    }
    {
        std::unique_lock writeLock{ mutex };
        // ...
        // read/write part
        // ...
     }
     // ... some other read part ...
 }

N3568提案中有一个std::upgrade_lock,但它没有成为标准。

njthzxwz

njthzxwz2#

您使用adopt_lock调用unique_lock,它不会在构造时锁定互斥锁。您可能希望在锁定unique_lock之前释放readLock。或者,您可以为unique_lock部分添加单独的互斥锁。

相关问题