赋值=和减法赋值 - = C中的原子操作?

时间:2011-07-04 18:46:21

标签: c atomic

int b = 1000;
b -= 20;

上述任何一项原子操作?什么是C中的原子操作?

5 个答案:

答案 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,它是一个整数类型   即使在存在的情况下也可以作为原子实体访问的对象   异步中断。