std::mutex lock函数和std::lock_guard<std::mutex>之间的区别是什么?

14
基本上,标题就已经解释得很清楚了。 我是这样使用它的:
  • 代码是用Objective-C ++编写的。
  • Objective-C类对不同目的函数进行并发调用。
  • 我使用std::mutex来锁定和解锁整个类中跨越std::vector<T>编辑选项,因为C ++ std容器不是线程安全的。
2个回答

23
使用lock_guard会在其作用域结束时自动解锁互斥量。这样,当返回时或抛出异常时,不可能忘记解锁它。你应该总是优先使用lock_guardunique_lock,而不是使用mutex::lock()。请参见http://kayari.org/cxx/antipatterns.html#locking-mutex lock_guard是一种RAIISBRM类型的示例。

1

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,但是当您尝试构建应用程序时,它将失败,因为苹果已更新了头文件,但未更新libc++本身。
因此,对于Objective-C应用程序而言,使用GCD可能更方便,同时为所有C++容器分配几个队列,并在需要的地方放置信号量。请参阅这个优秀的comparison

“你需要为每次需要锁定互斥量分配另一个类实例来作为保护,这是什么意思?”你让lock_guard听起来很糟糕。 - Jonathan Wakely
如果你需要它,那也不算太糟糕。但是,如果你以一种避免死锁的方式构建应用程序,你就不需要它了。 - ashvardanian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接