【问题标题】:Difference between std::mutex lock function and std::lock_guard<std::mutex>?std::mutex 锁定函数和 std::lock_guard<std::mutex> 的区别?
【发布时间】:2026-01-13 00:20:07
【问题描述】:

基本上,标题是不言自明的。 我以以下方式使用它:

  • 代码在 Objective-C++ 中。
  • Objective-C 类对不同用途的函数进行并发调用。
  • 我在整个类中使用 std::mutexlockunlock std::vector&lt;T&gt; 编辑选项,因为 C++ 标准容器不是线程安全的。

【问题讨论】:

    标签: multithreading c++11 mutex objective-c++


    【解决方案1】:

    使用lock_guard 会在互斥锁超出范围时自动再次解锁。这使得在返回或抛出异常时不可能忘记解锁它。您应该始终更喜欢使用lock_guardunique_lock 而不是mutex::lock()。见http://kayari.org/cxx/antipatterns.html#locking-mutex

    lock_guardRAIISBRM 类型的示例。

    【讨论】:

      【解决方案2】:

      std::lock_guard 仅用于两个目的:

      1. 在销毁期间自动解锁互斥锁(无需致电.unlock())。
      2. 允许同时锁定多个互斥锁以克服死锁问题。

      对于最后一个用例,您需要std::adopt_lock 标志:

      std::lock(mutex_one, mutex_two);
      std::lock_guard<std::mutex> lockPurposeOne(mutex_one, std::adopt_lock);
      std::lock_guard<std::mutex> lockPurposeTwo(mutex_two, std::adopt_lock);
      

      另一方面,每次需要锁定互斥锁时,都需要为守卫分配另一个类实例,因为std::lock_guard 没有成员函数。如果您需要具有解锁功能的防护,请查看std::unique_lock 类。您也可以考虑使用std::shared_lock 来并行读取您的向量。

      您可能会注意到,std::shared_lock 类在头文件中被注释并且只能使用 C++17 访问。根据头文件,你可以使用std::shared_timed_mutex,但是当你尝试构建应用程序时它会失败,因为Apple更新了头文件,而不是libc++本身。

      因此,对于 Objective-C 应用程序,使用 GCD 可能更方便,同时为所有 C++ 容器分配几个队列,并在需要的地方放置信号量。看看这个出色的comparison

      【讨论】:

      • "每次你需要锁定互斥锁时,你需要为守卫分配另一个类实例"是什么意思?你让lock_guard听起来很糟糕。
      • 如果你需要它也不错。但是,如果您以这种方式构建应用程序,则不会出现这种死锁——您不需要它。