windows - BSD 以外的操作系统的原子加载/存储?

标签 windows macos solaris atomic freebsd

在 BSD 提供的原子操作中(在 atomic(9) 手册页中给出),有 atomic_load_acq_int()atomic_store_rel_int()。在寻找其他操作系统的等效项时(例如,通过阅读 Mac OS X 的 atomic(3) 手册页,Solaris 的 atomic_ops(3C) 手册页,和 Windows 的 Interlocked*() 函数),似乎没有任何(明显的)等价物用于原子地读/写 int

这是因为它暗示那些为 int 读/写的操作系统默认保证是原子的吗? (或者你必须在 C/C++ 中使用 declare them volatile 吗?)

如果不是,那么如何在这些操作系统上对 int 进行原子读/写?

(可以通过返回原子加 0 的结果来模拟原子读取,但是没有等效的原子写入。)

最佳答案

我觉得你们混在一起了atomic memory accesscache coherence .前者是在软件中构建同步原语(自旋锁、信号量和互斥量)所需的硬件支持,而后者是对工作在同一总线上的多个芯片(多个 CPU 和外围设备)的硬件支持,并且具有主内存的一致 View 。

不同的编译器/库为第一个提供不同的实用程序。例如,这里是 GCC intrinsics for atomic memory access .它们都归结为生成 compare-and-swapload-linked/store-conditional基于指令 block 取决于平台支持。编译您的源代码,例如,为 GCC 使用 -S 并查看生成的汇编器。

您不必为缓存一致性明确地做任何事情——它都在硬件中处理——但它肯定有助于理解它是如何工作的,以避免像 cache line ping-pong 这样的事情发生。 .

有了这一切, aligned 单个单词的读取和写入在所有商品平台上都是原子的(如果我在这里错了,请有人纠正我)。由于 int 的大小小于或等于处理器字,因此您已被覆盖(请参阅上面的 GCC 内置链接)。

重要的是读写的顺序。这就是架构内存模型很重要的地方。它规定了硬件可以和不能对哪些操作进行重新排序。示例是更新链表——在项目本身处于一致状态之前,您不希望其他 CPU 看到链接的新项目。明确 memory barriers (通常也称为“内存栅栏”)可能是必需的。 Acquire 屏障确保后续操作不会在屏障之前重新排序(假设您在项目内容之前读取链表项目指针),Release 屏障确保之前的操作在屏障之后不会重新排序(您在写入新链接指针之前写入项目内容)。

volatile 经常被误解为与上述所有内容相关。事实上,它只是告诉编译器不要在寄存器中缓存变量值,而是在每次访问时从内存中读取它。许多人认为它是 "almost useless"用于并发编程。

很抱歉回复冗长。希望这会稍微清除它。

编辑:

即将推出的 C++0x 标准最终解决了并发问题,请参阅 Hans Boehm's C++ memory model papers了解更多详情。

关于windows - BSD 以外的操作系统的原子加载/存储?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3223602/

相关文章:

python - 在 Windows 中增加 python 的可用内存

macos - 从 sed 中提取多个捕获组到变量

macos - 为什么在我的 dtruss 跟踪中没有任何 execve 调用?

database - Solaris - 同步磁盘刷新/同步同步?

javascript - Electron - preload.js 未加载并且在 Windows 10 上发生错误

windows - 对检查互联网连接的模块进行单元测试

path - Ansible:如何为 solaris 全局设置 PATH

java - 如何知道 Unix 中正在运行什么类?

java - 数据库连接代码运行在 Linux 而不是 Windows

java - 如何获取jar内的资源路径