c – 为什么std :: lock_guard在使用std :: adopt_lock后释放锁
在下面的示例中,调用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()内是否有正确的方法来确保其关键部分受到保护? 解决方法
是.使用unique_lock< std :: mutex>在foo而不是lock_guard,传递一个const&将unique_lock作为要检查的参数,以便它可以验证正确的互斥锁被保存: 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. } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |