std::mutex 锁定函数和 std::lock_guard<std::mutex> 的区别?
Posted
技术标签:
【中文标题】std::mutex 锁定函数和 std::lock_guard<std::mutex> 的区别?【英文标题】:Difference between std::mutex lock function and std::lock_guard<std::mutex>? 【发布时间】:2016-07-12 23:28:12 【问题描述】:基本上,标题是不言自明的。 我以以下方式使用它:
代码在 Objective-C++ 中。 Objective-C 类对不同用途的函数进行并发调用。 我在整个类中使用std::mutex
到 lock
和 unlock
std::vector<T>
编辑选项,因为 C++ 标准容器不是线程安全的。
【问题讨论】:
【参考方案1】:使用lock_guard
会在互斥锁超出范围时自动再次解锁。这使得在返回或抛出异常时不可能忘记解锁它。您应该始终更喜欢使用lock_guard
或unique_lock
而不是mutex::lock()
。见http://kayari.org/cxx/antipatterns.html#locking-mutex
lock_guard
是 RAII 或 SBRM 类型的示例。
【讨论】:
【参考方案2】:std::lock_guard
仅用于两个目的:
-
在销毁期间自动解锁互斥锁(无需致电
.unlock()
)。
允许同时锁定多个互斥锁以克服死锁问题。
对于最后一个用例,您需要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
听起来很糟糕。
如果你需要它也不错。但是,如果您以这种方式构建应用程序,则不会出现这种死锁——您不需要它。以上是关于std::mutex 锁定函数和 std::lock_guard<std::mutex> 的区别?的主要内容,如果未能解决你的问题,请参考以下文章