我正在研究C ++ 11mutex
和之间的区别atomic
。
据我了解,mutex
是一种锁定机制,它是基于OS /内核实现的。例如,Linux提供了一种机制futex
。在的帮助下futex
,我们可以实现mutex
和实现semaphore
。此外,我知道这futex
是通过低级原子操作(例如CompareAndSet
)实现的CompareAndSwap
。
对于std::atomic
,我知道它是基于C ++ 11引入的内存模型实现的。但是,我不知道如何在底层实现内存模型。如果它也通过原子操作之类的实现CompareAndSet
,std::atomic
和之间有什么区别mutex
?
简而言之,如果std::atomic::is_lock_free
给我一个false
,那么,我要说std::atomic
与相同mutex
。但是,如果它给我一个true
,它如何在低水平实现?
如果原子操作为lock_free
,则它们的实现方式可能与实现互斥锁的组件相同。毕竟,要锁定互斥锁,您确实需要某种原子操作来确保只有一个线程锁定该互斥锁。
区别在于,无锁定的原子操作没有“锁定”状态。让我们比较两种可能的方式来对变量进行原子递增:
首先,互斥方式。我们锁定一个互斥锁,我们以递增方式写入变量,然后解锁互斥锁。如果线程在读增量写入期间被中断,则其他尝试执行相同操作的线程将阻止尝试锁定互斥锁。(有关std :: atomic的锁在哪里,有关它在某些实际实现中的工作原理,对于太大而无法lock_free的对象,请参见。)
第二,原子方式。CPU仅在包含一条我们要修改的变量的高速缓存行中锁定一次单个读增量写入指令的持续时间。(这意味着CPU延迟了对MESI请求的响应,以使无效或共享高速缓存行,保持独占访问,因此没有其他CPU可以查看它。MESI高速缓存一致性始终要求高速缓存行具有独占所有权,然后内核才能对其进行修改,因此这是便宜(如果我们已经拥有该线路)。在指令执行期间,我们不可能被打断。另一个尝试访问此变量的线程在最坏的情况下必须等待缓存一致性硬件找出谁可以修改内存位置。
那么我们如何锁定互斥锁呢?可能我们执行原子比较和交换。因此,轻原子操作是组合重互斥操作的基元。
当然,这都是特定于平台的。但这就是您可能会使用的典型现代平台。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句