int b = 1000;
b -= 20;
上述任何一项原子操作?什么是C中的原子操作?
答案 0 :(得分:8)
这取决于实施。根据标准,C中没有任何原子。如果你需要原子操作,你可以查看编译器的内置函数。
答案 1 :(得分:3)
它取决于架构/实现。
如果你想进行原子操作,我认为sig_atomic_t
类型是由C99标准化的,但不确定。
来自GNU LibC文档:
实际上,您可以假设int和其他不超过int的整数类型都是原子的。您还可以假设指针类型是原子的;这很方便。这两个都适用于GNU C库支持的所有机器,以及我们所知道的所有POSIX系统。
答案 2 :(得分:1)
增加和减少数字不是C中的原子操作。某些体系结构支持原子递增和递减指令,但不能保证编译器会使用它们。您可以在Qt引用计数中查看示例。它使用原子引用计数,在某些平台上使用特定于平台的汇编代码实现,其余则使用互斥锁来锁定计数器。
如果您没有在代码的性能关键部分中递增或递减,则只需在执行时使用互斥锁。如果您在代码的性能关键部分中使用它,您可能希望尝试以不使用共享内存的方式重写代码,以便从多个位置访问此操作,或者使用更高粒度的互斥锁这样它们不会影响性能,或者使用程序集来确保操作是原子的。
答案 3 :(得分:1)
这个链接在我看来是在正确的轨道上告诉我们C中的原子操作:
http://odetocode.com/blogs/scott/archive/2006/05/17/atomic-operations.aspx
它说,“......计算机科学采用”原子操作“这个术语来描述一个不可分割且不会被其他执行线程中断的指令。”
根据该定义,原始问题中的第一行代码
int b=1000;
b-=20;
应该是原子操作。如果CPU的指令集包括直接从存储器中减去的指令,则第二个可以是原子操作。我认为这样的原因是第一个代码行很可能只需要一个汇编(机器)指令。并且指令要么执行要么不执行。我认为任何机器指令都不能在中间被中断。
在同一个链接上,“如果线程A正在将32位值作为原子操作写入内存,则线程B将永远无法读取内存位置并且只能看到写出的32位中的前16位“。似乎任何单个机器指令都不能在中间被中断,因此在线程之间会自动成为原子。
答案 4 :(得分:-1)
引自ISO C89,7.7信号处理<signal.h>
定义的类型是
sig_atomic_t
,它是一个整数类型 即使在存在的情况下也可以作为原子实体访问的对象 异步中断。