问题
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?
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
回答1:
Prior to C11
The C library doesn't have any.
On Linux, gcc provides some -- look for __sync_fetch_and_add
, __sync_fetch_and_sub
, and so on.
In the case of Windows, look for InterlockedIncrement
, InterlockedDecrement``,
InterlockedExchange`, and so on. 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).
On Solaris, it'll depend. Presumably if you use gcc, it'll probably (again) have the same built-ins it does under Linux. Otherwise, there are libraries floating around, but nothing really standardized.
C11
C11 added a (reasonably) complete set of atomic operations and atomic types. 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
). There are also fence
functions, such as atomic_thread_fence
and atomic_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
. Those are typedef
names defined in <stdatomic.h>
. To avoid conflicts with any existing names, you can omit the header; the compiler itself uses names in the implementor's namespace (e.g., _Atomic_uint_least32_t
instead of atomic_uint_least32_t
).
回答2:
'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').
回答3:
Across all supported platforms, you can use use GLib's atomic operations. On platforms which have atomic operations built-in (e.g. assembly instructions), glib will use them. 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.
回答4:
Not sure what you mean by the C runtime library. 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. 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.
回答5:
On Windows, there are InterlockedExchange and the like. For Linux, you can take glibc's atomic macros - they're portable (see 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).
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.
来源:https://stackoverflow.com/questions/2302674/functions-for-performing-atomic-operations