是否手动解锁 lock_guard 未定义/错误设计?

新手上路,请多包涵

我有这样的代码:

 do {
    lock_guard<mutex> lck(globalMtx);
    auto itr = someMap.end();
    for (/*conditions*/){
        //do stuff with itr and someMap
        // if a certain condition is met, we exit function with a return
        // globalMtx needs to be unlocked at that time
    }
    if (itr == someMap.end()){
        // I need to unlock the globalMtx here
        globalMtx.unlock()
        // A command is sent to modify someMap before we try again
        this_thread::sleep_for( chrono::seconds( 5 ) );
    } else {
        break;
    }
} while (true);

正如您在 if 范围中看到的那样,我需要解锁 globalMtx,以便我可以在再次通过之前修改“someMap”。我在许多线程/论坛/无论使用 mutex.lock()/unlock() 手动锁定互斥锁是一个坏主意,并且通常不再使用 c++11 或更高版本。

那么在这种情况下我可以做些什么来根据需要控制互斥锁,同时仍然防止任何离开范围保持互斥锁锁定的情况?

原文由 user1324674 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 545
2 个回答

不,在这种情况下,您不应该直接调用 std::mutex::unlock() ,因为 std::lock_guard 析构函数会再次调用 std::mutex::unlock() 而这会导致 UB。您可以改用 std::unique_lock ,它不像 std::lock_guard 那样轻量级,但允许您调用 unlock()

 std::unique_lock<mutex> lck(globalMtx);
...
lck.unlock(); // lck object is aware that globalMtx is released and would do nothing in it's dtor after this

原文由 Slava 发布,翻译遵循 CC BY-SA 3.0 许可协议

编写一个像 lock_guard 这样的包装器,它跟踪互斥锁是否被持有,并且只有在持有时才解锁。

原文由 SoronelHaetir 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题