【问题标题】:c++ std::lock_guard scope reachc++ std::lock_guard 作用域到达
【发布时间】:2020-09-25 19:13:46
【问题描述】:

假设我有一个获取锁并执行由参数传递的函数的函数:

template <typename T>
T acquireLock(std::mutex& _lock, const std::function<T()>& execution) {

  try {
    std::lock_guard<std::mutex> mutex (_lock);

    return execution();

  } catch (std::logic_error& error) {

    std::cerr << "[exception caught]\n\t" << error.what() << std::endl;

  }

  return false;
}

另外,我有一个类需要为其某些方法获取所述锁。

class MyThreadSafeClass {

 public:

  bool Init();
  bool StopApi();
  unsigned int GetValue() {

      auto ret = acquireLock<unsigned int>(_lock, [this]() -> unsigned int {

        // does some work that's not thread-safe...
        return value;

      });

      return ret;
  }

 private:

  bool _ready = false;
  std::mutex _lock;

};

我的疑问是,每当我调用GetValue() 时,查看我的acquireLock() 方法,execution() 调用是否也受到锁定范围的影响?

auto myClass = new MyThreadSafeClass();
myClass->GetValue();

查看this,更具体地说:

当一个 lock_guard 对象被创建时,它会尝试获取 它给出的互斥锁。当控制离开控制范围时 lock_guard 对象被创建,lock_guard 被破坏并且 互斥锁被释放。

我仍然不清楚execution() 代码内部发生的事情是否仍受锁定范围的影响。

【问题讨论】:

  • 它是......它在lock_guard的范围内运行。它的范围是直到 return 被执行,并且直到 execute 被执行后才会发生。
  • 目前还不清楚你到底在问什么。首先构造lock_guard,获取互斥锁。然后调用execution(),同时锁定互斥锁。当execution() 退出时,lock_guard 超出范围,释放互斥锁。
  • 你的意思是,当函数execution在被调用时试图获取同一个锁时会发生什么?
  • 不,@RemyLebeau 回答的正是我的意思!引用:“当 execution() 退出时, lock_guard 超出范围,释放互斥锁”。对不起,我现在明白了

标签: c++ mutex locks


【解决方案1】:

根据[stmt.return]/p3

  1. 调用结果的复制初始化在由 return 语句的操作数建立的完整表达式末尾处的临时对象的销毁之前排序,而后者又在局部变量的销毁之前排序([stmt.jump]) 包含 return 语句的块。

所以我们得到:

  1. 互斥锁已锁定
  2. execution() 在持有锁时被调用
  3. 锁被释放
  4. 评估值返回给调用者(或输入catch子句)

换句话说,是的,它会按预期工作。


无关说明:std::function 效率不高。可调用类型的模板应该会更好:

template<typename F>
auto doLocked(std::mutex& _lock, F const& f) -> decltype(f()) {
    std::lock_guard<std::mutex> lock(_lock);
    return f();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-18
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多