gpt4 book ai didi

c++ - 为什么std::lock_guard在使用std::adopt_lock之后释放锁?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:12 27 4
gpt4 key购买 nike

在下面的示例中,方法 foo() 被调用,它获得互斥体的所有权,并将其锁定。然后它调用 check(),它获得了所有权,但假定互斥体已经被锁定,因此使用 std::adopt_lock 简单地采用它。

但是当 check() 完成时,互斥锁被解锁。所以当 foo() 继续时,我试图保护的部分实际上不再受到保护。

#include <mutex>
static std::mutex sessionLock;

bool check();

void foo() {
std::lock_guard<std::mutex> guard(sessionLock);
if (check()) {
// Do transaction
// Wait... the mutex is unlocked here!
}
}

bool check() {
std::lock_guard<std::mutex> guard(sessionLock, std::adopt_lock);
// Critical section
return true;
}

int main() {
foo();
return 0;
}

我发现这种行为非常不直观。如果子方法决定使用 std::adopt_lock 获取锁的所有权(即它不调用 lock()),它不应该也释放不调用 unlock() 的所有权?该标准另有规定,但我很好奇这是否是疏忽,或者是否有特定原因是预期的。

这可以使用 std::recursive_mutex 重写,尽管在这种情况下使用常规 std::mutex 中是否有正确的方法check() 以确保其关键部分受到保护?

最佳答案

...though in this case where a regular std::mutex is used, is there a proper way inside check() to ensure its critical section is guarded?

是的。使用 unique_lock<std::mutex>foo而不是 lock_guard , 并传递 const&那个unique_lock作为 check 的参数以便它可以验证是否持有正确的互斥锁:

bool check(const std::unique_lock<std::mutex>& guard) {
assert(guard.owns_lock()); // guard holds *some* mutex...
assert(guard.mutex() == &sessionLock); // ...it is in fact sessionLock
// Critical section
return true;
}

void foo() {
std::unique_lock<std::mutex> guard(sessionLock);
if (check(guard)) {
// Do transaction - guard is still locked.
}
}

关于c++ - 为什么std::lock_guard在使用std::adopt_lock之后释放锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34169341/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com