多线程中互斥锁与原子性的区别

一个好的解释,

原子操作是不能细分为更小部分的操作。因此,它永远不会半途而废,因此您可以保证它将始终以一致的状态被观察到。例如,现代硬件实现原子比较和交换操作。

互斥锁排除其他进程或线程执行同一段代码(关键段)。基本上,它确保最多一个线程执行给定的代码段。互斥锁也称为锁。

在幕后,锁必须以某种方式使用硬件实现,并且实现必须利用底层硬件的原子性保证。

大多数非平凡操作都不能成为原子操作,因此必须在关键部分执行时使用锁来阻止其他线程操作,否则必须仔细设计无锁算法,以确保所有关键状态更改操作都可以使用原子操作安全实现。

参考:

 


多线程等待的优选方案:

使用 C++ 标准库提供的工具去等待事件的发生。通过另一线程触发等待事件的机制是最基本的唤醒方式(例如:流水线上存在额外的任务时),这种机制就称为“条件变量”。从概念上来说,一个条件变量会与多个事件或其他条件相关,并且一个或多个线程会等待条件的达成。当某些线程被终止时,为了唤醒等待线程(允许等待线程继续执行),终止线程将会向等待着的线程广播“条件达成”的信息。

一般用 std::condition_variable 和 std::condition_variable_any 

这两个实现都包含在 <condition_variable> 头文件的声明中。两者都需要与一个互斥量一起才能工作(互斥量是为了同步);前者仅限于与 std::mutex 一起工作,而后者可以和任何满足最低标准的互斥量一起工作,从而加上了 _any 的后缀。因为  std::condition_variable_any 更加通用,这就可能从体积、性能,以及系统资源的使用方面产生额外的开销,所以 std::condition_variable 一般作为首选的类型,当对灵活性有硬性要求时,我们才会去考虑 std::condition_variable_any。

代码示例参考:std::condition_variable::notify_one

 

posted @ 2023-01-11 19:13  strive-sun  阅读(124)  评论(0编辑  收藏  举报