简体   繁体   English

执行原子操作的功能

[英]Functions for performing atomic operations

Are there functions for performing atomic operations (like increment / decrement of an integer) etc supported by C Run time library or any other utility libraries? C运行时库或任何其他实用程序库是否支持执行原子操作(例如整数的增/减)等功能?

If yes, what all operations can be made atomic using such functions? 如果是,那么使用这些功能可以使所有操作变为原子操作?

Will it be more beneficial to use such functions than the normal synchronization primitives like mutex etc? 使用此类功能是否比诸如互斥锁等常规同步原语更有利?

OS : Windows, Linux, Solaris & VxWorks 操作系统:Windows,Linux,Solaris和VxWorks

Prior to C11 C11之前

The C library doesn't have any. C库没有任何库。

On Linux, gcc provides some -- look for __sync_fetch_and_add , __sync_fetch_and_sub , and so on. 在Linux上,gcc提供了一些-查找__sync_fetch_and_add__sync_fetch_and_sub等等。

In the case of Windows, look for InterlockedIncrement , InterlockedDecrement``, InterlockedExchange`, and so on. 对于Windows,请查找InterlockedIncrementInterlockedDecrement``, InterlockedExchange`等。 If you use gcc on Windows, I'd guess it also has the same built-ins as it does on Linux (though I haven't verified that). 如果您在Windows上使用gcc,我想它也具有与Linux上相同的内置功能(尽管我尚未验证)。

On Solaris, it'll depend. 在Solaris上,这取决于。 Presumably if you use gcc, it'll probably (again) have the same built-ins it does under Linux. 据推测,如果您使用gcc,它可能(再次)具有与Linux下相同的内置函数。 Otherwise, there are libraries floating around, but nothing really standardized. 否则,到处都是库,但是没有真正标准化的库。

C11 C11

C11 added a (reasonably) complete set of atomic operations and atomic types. C11添加了(合理地)完整的原子操作和原子类型的集合。 The operations include things like atomic_fetch_add and atomic_fetch_sum (and *_explicit versions of same that let you specify the ordering model you need, where the default ones always use memory_order_seq_cst ). 这些操作包括atomic_fetch_addatomic_fetch_sum类的东西(以及*_explicit的相同版本,可让您指定所需的排序模型,其中默认模型始终使用memory_order_seq_cst )。 There are also fence functions, such as atomic_thread_fence and atomic_signal_fence . 也有fence功能,例如atomic_thread_fenceatomic_signal_fence

The types correspond to each of the normal integer types--for example, atomic_int8_t corresponding to int8_t and atomic_uint_least64_t corrsponding to uint_least64_t . 类型对应于每个正常整数类型-例如, atomic_int8_t对应于int8_tatomic_uint_least64_t造成相应于uint_least64_t Those are typedef names defined in <stdatomic.h> . 这些是在<stdatomic.h>定义的typedef名称。 To avoid conflicts with any existing names, you can omit the header; 为了避免与任何现有名称冲突,您可以省略标题。 the compiler itself uses names in the implementor's namespace (eg, _Atomic_uint_least32_t instead of atomic_uint_least32_t ). 编译器本身使用实现者名称空间中的名称(例如_Atomic_uint_least32_t而不是atomic_uint_least32_t )。

'Beneficial' is situational. “有益”是情境。 Always, performance depends on circumstances. 始终,性能取决于环境。 You may expect something wonderful to happen when you switch out a mutex for something like this, but you may get no benefit (if it's not that popular of a case) or make things worse (if you accidently create a 'spin-lock'). 当您为这样的互斥对象切换出互斥锁时,您可能会期望发生一些奇妙的事情,但是您可能没有任何好处(如果这种情况不那么流行)或使情况变得更糟(如果您不小心创建了“自旋锁”) 。

Across all supported platforms, you can use use GLib's atomic operations . 在所有受支持的平台上,您都可以使用GLib的原子操作 On platforms which have atomic operations built-in (eg assembly instructions), glib will use them. 在内置了原子操作(例如,汇编指令)的平台上,glib将使用它们。 On other platforms, it will fall back to using mutexes. 在其他平台上,它将退回到使用互斥锁。

I think that atomic operations can give you a speed boost, even if mutexes are implemented using them. 我认为,即使使用互斥操作实现原子操作,也可以提高速度。 With the mutex, you will have at least two atomic ops (lock & unlock), plus the actual operation. 使用互斥锁,您将至少有两个基本操作(锁定和解锁)以及实际操作。 If the atomic op is available, it's a single operation. 如果原子操作可用,则只需一次操作。

Not sure what you mean by the C runtime library. 不确定C运行时库的含义。 The language proper, or the standard library does not provide you with any means to do this. 适当的语言或标准库不为您提供执行此操作的任何方法。 You'd need to use a OS specific library/API. 您需要使用特定于操作系统的库/ API。 Also, don't be fooled by sig_atomic_t -- they are not what it seems at first glance and are useful only in the context of signal handlers. 另外,不要被sig_atomic_t -乍看之下它们并不sig_atomic_t它们那样,仅在信号处理程序的上下文中才有用。

On Windows, there are InterlockedExchange and the like. 在Windows上,有InterlockedExchange等。 For Linux, you can take glibc's atomic macros - they're portable (see i486 atomic.h ). 对于Linux,您可以使用glibc的原子宏 -它们是可移植的(请参阅i486 atomic.h )。 I don't know a solution for the other operating systems. 我不知道其他操作系统的解决方案。

In general, you can use the xchg instruction on x86 for atomic operations (works on Dual Core CPUs, too). 通常,您可以在x86上使用xchg指令进行原子操作(也可以在双核CPU上运行)。

As to your second question, no, I don't think that using atomic operations will be faster than using mutexes. 关于第二个问题,不,我认为使用原子操作不会比使用互斥体更快。 For instance, the pthreads library already implements mutexes with atomic operations, which is very fast. 例如,pthreads库已经使用原子操作实现了互斥锁,这非常快。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM