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

c – 为什么std :: lock_guard在使用std :: adopt_lock后释放锁?,第1张

概述在下面的示例中,调用foo()方法,获取互斥锁的所有权并锁定它.然后它调用check(),它获取所有权,但假设互斥锁已经被锁定,因此只需使用std :: adopt_lock来采用它. 但是当check()完成时,互斥锁会被解锁.因此,当foo()继续时,我试图保护的部分实际上不再受到保护. #include <mutex>static std::mutex sessionLock;bool 在下面的示例中,调用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作为要检查的参数,以便它可以验证正确的互斥锁被保存:

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后释放锁?全部内容,希望文章能够帮你解决c – 为什么std :: lock_guard在使用std :: adopt_lock后释放锁?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1228008.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存