【问题标题】:How to use lock_guard in this conditional如何在这个条件下使用 lock_guard
【发布时间】:2016-11-29 03:35:33
【问题描述】:

一个线程有以下控制流:

mutex.lock()
if (condition) {
    // do synced things
    mutex.unlock();
    // do parallel things
} else {
    // do other synced things
    mutex.unlock();
    // do other parallel things
}

注意四个do 部分如何执行不同的事情。

如何将直接调用 lock 和 unlock 替换为使用 std::lock_guard

【问题讨论】:

  • condition是否需要在互斥锁的范围内?
  • @NathanOliver 是的,访问时必须锁定。
  • 就个人而言,我会使用unique_lock 并仍然手动解锁互斥锁。您可以获得 RAII 并控制解锁过程
  • @KABoissonneault 恕我直言,这是最干净的方法。它可以防止你有多个 if 就像 Xarn 的答案。

标签: c++ multithreading


【解决方案1】:

std::unique_lock 看起来像您要查找的内容。语义类似于std::lock_guard,但allows more sophisticated constructs。因此,在您的情况下,您仍然可以获得异常安全性,但也可以提前明确解锁。比如:

std::unique_lock<decltype(mutex)> guard(mutex); // calls mutex.lock() like lock_guard
if (condition) {
    // do synced things
    guard.unlock();
    // do parallel things
} else {
    // do other synced things
    guard.unlock();
    // do other parallel things
}
// unlocks on leaving scope, if held similar to lock_guard

【讨论】:

    【解决方案2】:
    bool cond;
    {
        std::lock_guard<std::mutex> lg(mutex);
        cond = global_condition;
        if (cond){
            // do some synced stuff
        } else {
            // do the other synced stuff
        }
    }
    
    if (cond){
        // do parallel stuff
    } else {
        // do the other parallel stuff
    }
    

    由于这两种情况下的并行操作都是在解锁保护全局条件的互斥锁后完成的,这意味着条件要么不能改变,要么我们不在乎它是否改变。因此我们可以根据保存的值再次保存该值和 if-else。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 2017-10-06
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      相关资源
      最近更新 更多