考虑以下函数:
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
。对我来说,它看起来完全合法,但在玩了一圈之后,结果发现一些死锁开始出现(不一定在函数中,但很明显,这个变化是问题的根本原因)
有谁能详细说明一下这种方法是否定义良好,以及它究竟为什么会出现死锁问题?
2条答案
按热度按时间e5njpo681#
看起来你想把共享锁升级为唯一锁。你做错了-
std::shared_mutex
不是递归的,不能升级。先释放共享锁,然后正常地独占锁。在N3568提案中有一个
std::upgrade_lock
,但它没有成为标准。njthzxwz2#
您使用adopt_lock调用unique_lock,它不会在构造时锁定互斥锁。您可能希望在锁定unique_lock之前释放readLock。或者,您可以为unique_lock部分添加单独的互斥锁。