是否有用于执行C运行时库或任何其他实用程序库支持的原子操作(如递增/递减整数)等的函数?
如果是,那么使用这些函数可以使所有操作成为原子?
使用这些函数比使用mutex等常规同步原语更有益吗?
操作系统:Windows,Linux,Solaris和VxWorks的
答案 0 :(得分:7)
C库没有。
在Linux上,gcc提供了一些 - 查找__sync_fetch_and_add
,__sync_fetch_and_sub
等等。
如果是Windows,请查找InterlockedIncrement
,InterlockedDecrement``,
InterlockedExchange`,依此类推。如果你在Windows上使用gcc,我猜它也有与Linux上相同的内置函数(尽管我还没有验证过)。
在Solaris上,它将取决于。大概如果你使用gcc,它可能(再次)拥有与它在Linux下相同的内置函数。否则,有些库会浮动,但没有真正标准化。
C11增加了一套(合理的)完整的原子操作和原子类型。这些操作包括atomic_fetch_add
和atomic_fetch_sum
(以及*_explicit
版本的操作,可让您指定所需的排序模型,默认值始终使用memory_order_seq_cst
)。还有fence
个函数,例如atomic_thread_fence
和atomic_signal_fence
。
这些类型对应于每个普通整数类型 - 例如,atomic_int8_t
对应int8_t
,atomic_uint_least64_t
对应uint_least64_t
。这些是typedef
中定义的<stdatomic.h>
个名称。为避免与任何现有名称冲突,可以省略标题;编译器本身使用实现者名称空间中的名称(例如,_Atomic_uint_least32_t
而不是atomic_uint_least32_t
)。
答案 1 :(得分:1)
'有益'是情境。总是,表现取决于具体情况。当你为这样的事情换掉一个互斥体时,你可能会期待一些奇妙的事情发生,但你可能没有任何好处(如果它不是那种流行的情况)或者让事情变得更糟(如果你意外地创造了'自旋锁')
答案 2 :(得分:1)
在所有支持的平台上,您可以使用GLib's atomic operations。在内置原子操作的平台上(例如汇编指令),glib将使用它们。在其他平台上,它将回归到使用互斥锁。
我认为原子操作可以提高速度,即使使用它们实现互斥锁也是如此。使用互斥锁,您将至少有两个原子操作(锁定和解锁),以及实际操作。如果原子操作可用,则只需一次操作。
答案 3 :(得分:0)
不确定C运行时库的含义。正确的语言或标准库不提供任何方法来执行此操作。您需要使用特定于操作系统的库/ API。此外,不要被sig_atomic_t
愚弄 - 它们不是乍一看似乎只有在信号处理程序的上下文中才有用。
答案 4 :(得分:0)
在Windows上,有InterlockedExchange之类的内容。对于Linux,您可以使用glibc's atomic macros - 它们是可移植的(请参阅i486 atomic.h)。我不知道其他操作系统的解决方案。
通常,您可以在x86上使用xchg
指令进行原子操作(也适用于双核CPU)。
至于你的第二个问题,不,我不认为使用原子操作会比使用互斥锁更快。例如,pthreads库已经实现了具有原子操作的互斥体,这非常快。