
[英]incompatible types when assigning to type 'atomic_int' from type 'int'
[英]is `int` an atomic type?
引用gnu :
实际上,您可以假设 int 是原子的。 您还可以假设指针类型是原子的; 那很方便。 这两个假设在 GNU C 库支持的所有机器和我们所知的所有 POSIX 系统上都是正确的。
这怎么可能? 我见过的所有与锁相关的示例都是使用 int 计数器创建的,例如https://www.delftstack.com/howto/c/mutex-in-c/ 。
glibc 手册中的这段文字仅与volatile sig_atomic_t
在线程及其信号处理程序之间是安全的有关。 他们保证volatile int
也能在 GNU 系统中以这种方式工作。 请注意您省略的上下文:
为避免中断对变量访问的不确定性,您可以使用访问始终是原子的特定数据类型:sig_atomic_t。 读取和写入此数据类型保证在一条指令中发生,因此处理程序无法在访问的“中间”运行。
这与原子性无关。 其他线程或并发。 中断处理程序接管 CPU 并代替您的代码运行。 在任何时候都是异步的,但主线程和它的信号处理程序不会同时运行(尤其是在不同的 CPU 内核上)。
对于线程,原子性是不够的,您还需要保证线程之间的可见性(您可以从 _Atomic _Atomic int
和memory_order_relaxed
),并且有时可以通过更强的内存顺序获得排序。
请参阅为什么在 x86 上对自然对齐的变量原子进行整数赋值的早期部分? 有关为什么在您正在编译的目标上具有自然原子宽度的 C 类型的更多讨论对于大多数事情来说是不够的。
有时您还需要 RMW 原子性,例如执行 atomic_fetch_add 的能力,这样如果 1000 个这样的+=1
操作在多个线程中发生,总结果将类似于+=1000
。 为此,您绝对需要编译器支持(或内联 asm),例如 C11 _Atomic int
。 对于“int num”,num++ 可以是原子的吗?
保证int
是原子的意味着atomic_int
应该始终是无锁的,并且便宜,但这绝对并不意味着普通int
对于线程之间共享的数据是远程安全的。 那是数据争用 UB,即使您使用 GNU C asm(""::: "memory")
类的内存屏障来尝试让编译器不将值保存在寄存器中,您的代码也可能会中断很多有趣的地方比一些明显的破损机制更微妙的方式。 看看谁害怕一个糟糕的优化编译器? 在 LWN 上了解有关在 Linux 内核中执行此操作的一些注意事项,其中他们使用volatile
来实现原子性。
(有趣的事实:GNU C 至少事实上在 64 位机器上使用volatile int64_t
提供纯加载和纯存储原子性,这与普通int64_t
不同。ISO C 甚至不能保证volatile
,这就是为什么 Linux内核取决于用 GCC 或 clang 编译。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.