原子动作 - 互斥

时间:2011-03-01 09:31:35

标签: c++

我听说有一种被称为“原子动作”的东西比使用具有临界区的互斥量更快。 有人知道它是什么,我该如何使用它?

5 个答案:

答案 0 :(得分:6)

原子操作是CPU在同一总线访问期间读写内存的操作,这可以防止其他CPU或系统设备同时修改内存。例如。一个“测试和设置”操作,它可以“读取位置X的内存,如果它是0,将其设置为1,返回指示值是否已设置”,没有任何同时访问的机会。

维基百科的http://en.wikipedia.org/wiki/Linearizability描述了原子操作。

如果您在窗户上,请查看例如InterlockedTestExchange或InterlockedIncrement,它们是原子操作的包装器。

编辑:示例用法

可以使用测试和设置原子操作来实现自旋锁:

while (test_and_set(&x) == 1) ;

这将保持循环,直到当前线程将x设置为1.如果所有其他线程以相同的方式处理x,则其效果与互斥锁相同。

答案 1 :(得分:2)

原子动作仅指动作将由原则上不间断地由共同运行的线程/进程完成。

您可能正在寻找的是编译器中的原子内置函数。例如,GCC提供此集:http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Atomic-Builtins.html

这些通常使用CPU支持非常有效地实现。

答案 2 :(得分:1)

这是一种权衡。正如其他海报所述,原子操作是“试图抓住这面旗帜并在成功时归属”。它很快,但有缺点。

正确的互斥锁阻止需要进入临界区的线程。只有原子操作,等待的线程必须循环,直到它们获得标志 - 这浪费了CPU周期。另一个缺点是互斥锁保证公平访问 - 通常只是在FIFO队列中排队等待进程。使用自旋锁,存在资源匮乏的风险。

所以,简单的原子操作速度更快,但只有当没有太多的线程试图抓住关键部分时。

答案 3 :(得分:0)

由于给出了特定于GCC的答案,这里是VC ++特定的链接 - 列出的所有以_Interlocked开头的内在函数都是相关的:http://msdn.microsoft.com/en-us/library/hd9bdb82.aspx。另请注意,x64的内在函数比x86更多:http://msdn.microsoft.com/en-us/library/azcs88h2.aspx

答案 4 :(得分:0)

关键部分实现(当然在windows中)使用原子变量来检测是否是由另一个线程捕获的关键部分(cs),并且只有在发生真正的冲突时才进入内核端同步原语。因此,如果您需要保护一小段代码并且碰撞概率足够小,那么关键部分是一个很好的解决方案。 但是,如果受保护的代码除了递增/递减或测试和修改单个变量之外什么都不做,那么使用原子操作是正确的。

还有可能通过原子来保护更复杂的代码(google“锁定自由结构”和“事务性内存”以获取更多信息)

这是有趣但非常复杂的东西,如果一些简单的解决方案(如关键部分)也有效,可能不推荐使用。