C运行时库或任何其他实用程序库是否支持执行原子操作(如整数的递增/递减)等功能?
如果是,使用这些函数可以使所有操作成为原子操作吗?
使用这些功能会比互斥锁等普通同步原语更有益吗?
操作系统:Windows、Linux、Solaris 和 VxWorks
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
)。
“有益”是情境性的。始终,性能取决于环境。当您将互斥锁换成这样的事情时,您可能期望会发生一些奇妙的事情,但是您可能没有得到任何好处(如果它不是那么受欢迎的情况)或者使事情变得更糟(如果您不小心创建了一个“自旋锁”) .
在所有支持的平台上,您都可以使用GLib 的原子操作。在具有内置原子操作(例如汇编指令)的平台上,glib 将使用它们。在其他平台上,它将回退到使用互斥锁。
我认为原子操作可以提高速度,即使互斥锁是使用它们实现的。使用互斥锁,您将拥有至少两个原子操作(锁定和解锁)以及实际操作。如果原子操作可用,则它是单个操作。
不确定 C 运行时库是什么意思。适当的语言或标准库没有为您提供任何方法来执行此操作。您需要使用特定于操作系统的库/API。另外,不要被愚弄sig_atomic_t
——它们不是乍一看的那样,仅在信号处理程序的上下文中有用。
在 Windows 上,有InterlockedExchange等。对于 Linux,您可以使用glibc 的原子宏- 它们是可移植的(参见i486 atomic.h)。我不知道其他操作系统的解决方案。
通常,您可以将xchg
x86 上的指令用于原子操作(也适用于双核 CPU)。
至于你的第二个问题,不,我认为使用原子操作不会比使用互斥锁更快。例如,pthreads 库已经实现了具有原子操作的互斥锁,这非常快。