考虑以下功能:
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
用于它的所有部分。它工作正常,但作为优化的一部分,它用 std::shared_lock
包裹了一些部分。对我来说它看起来完全合法,但在玩弄之后发现一些死锁开始出现(不一定在函数中,但很明显这种变化是问题的根本原因)
任何人都可以详细说明这种方法是否定义明确以及为什么会出现死锁问题?
你用 adopt_lock 调用 unique_lock,它不会在构建时锁定互斥量。您可能希望在锁定 unique_lock 之前释放 readLock。或者,您可以为 unique_lock 部分添加一个单独的互斥锁。
看起来你正在尝试将共享锁升级为唯一锁。你做错了 -
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 ...
}
提案中有一个
std::upgrade_lock
N3568但没有进入标准