【问题标题】:Whats better std::lock_guard<std::mutex> lock(std::mutex mutex_var); or std::mutex mutex_var.lock();什么更好 std::lock_guard<std::mutex> lock(std::mutex mutex var);或 std::mutex mutex_var.lock();
【发布时间】:2017-03-28 22:33:52
【问题描述】:

我需要在一个函数内锁定一个 std::map 和两个 boost::multimap 的操作,因为我们有线程试图访问该函数(以及映射)。

我计划使用“std::mutex mutex_var”来保护操作它们的函数内的这些变量。所以我有“std::mutex mutex_var”变量。我对在函数开头使用“mutex_var.lock()”和在函数结尾使用“mutex_var.unlock()”感到困惑(OR)只是在函数开头使用 std::lock_guard?

为了清楚起见,该函数所做的只是在互斥体上添加内容。我也理解/我们不需要保护我们尝试查询地图的所有地方(因为它只是一个读取操作)。

请让我知道更好的选择,也请澄清我的阅读不需要保护的想法是否正确。

TIA

-R

【问题讨论】:

  • 你应该一次问一个问题。
  • 如果在锁定互斥锁时抛出异常会发生什么?
  • mutex.lock() 可能是一个问题,但我认为 std::lock_guard(mutex_var) 会很好,因为堆栈帧会消失,从而使 lock_guard 失去作用域从而释放锁。如果我错了,请纠正我。
  • “仅读取操作”不会使其成为原子操作,如果不是原子操作,则不安全。
  • 读操作是用keys查找maps,是不是可以不加锁的操作?它不会以任何方式改变地图。请让我知道我的想法是否正确。

标签: c++ mutex


【解决方案1】:

您应该(几乎)永远不要使用std::mutex::lock()std::mutex::try_lock()std::mutex::unlock(),始终使用std::lock_guardstd::unique_lock 与您的mutex_var。因为你不必写解锁,因为他们在销毁时正在这样做。所以你不能忘记它,即使同时抛出了异常。这称为RAII,是现代 C++ 代码所需要的

所以std::lock_guard 更好

对于

我也理解/我们不需要保护我们尝试查询地图的所有地方

通常你还是要保护那个读操作,因为你不知道什么时候有人想写。但这取决于您的设计,整个问题被称为readers-writer-problem,由于您似乎没有意识到这一点,我认为您的设计需要锁定所有步骤。

【讨论】:

    【解决方案2】:
    • 使用简单的互斥锁,如果所有线程都在读取线程,则不需要锁定资源。但是,如果在写入资源的线程中有一个或多个,您需要锁定所有线程,甚至是读取线程。
    • 有一种方法可以避免在没有写入线程时锁定资源,并在只有一个写入线程时锁定资源。您需要使用更复杂的锁定机制,您应该阅读有关 openforread 和 openforwrite 逻辑的内容。

    【讨论】:

      猜你喜欢
      • 2013-12-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-24
      • 2016-09-07
      • 1970-01-01
      • 2012-11-02
      相关资源
      最近更新 更多