GCC原子内置函数 [英] gcc atomic built-in functions

查看:195
本文介绍了GCC原子内置函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<一个href=\"http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Atomic-Builtins.html\">http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Atomic-Builtins.html

我认为有以下code增加VAR原子的值。

I believe that the following code increases the value of var atomically.

volatile int var = 0;
__sync_fetch_and_add( &var, 1 )

我明白了上面的codeS如下面的逻辑


  1. 加载变量var的地址

  2. 写数字1到变量var原子 - 通过寄存器/缓存,不知何故

不过,我怀疑下面是原子,太

However, I doubt if the following is atomic, too

volatile int var = 0;
volatile int num = 1;
__sync_fetch_and_add( &var, num )

因为它可能是为PTED

Since it may be interpreted as


  1. 加载变量var的地址

  2. 加载变量num的值到寄存器

  3. 写入值到变量var。

#2执行后,但在此之前#3,
在CPU /线程被中断,另一个CPU /线程更新
变量num的值。

After #2 is executed, but before #3, the CPU/thread gets interrupted and another CPU/thread updates the value of variable num.

在换言之,
当使用_ 同步的*()的gcc,
我可以使用一个变量,而不是一个常数,作为第二个参数?

In other words, when using _sync*() of gcc, can I use a variable, not a constant, as the second argument?

不打破它的原子?

推荐答案

的操作实际上是两个操作。

The operation is really two operations.

__sync_fetch_and_add( &var, num )

加载 NUM 是原子。它添加到 VAR 是原子。但是,当把在一起的两个原子操作不要让一个原子操作。这就是为什么它是如此难以创造新的无锁的数据结构。的一般来说,双线程安全的操作并不一定构成时让一个线程安全的操作。的这就是为什么它是如此难以做出正确的多线程应用程序的原因。

Loading num is atomic. Adding it to var is atomic. But two atomic operations do not make an atomic operation when put together. This is why it is so hard to invent new lock-free data structures. In general, two thread-safe operations do not necessarily make a thread-safe operation when composed. This is the reason why it is so difficult to make correct multithreaded applications.

您看, __ sync_fetch_and_add 确实的原子,但它像一个普通的功能 - 所以它需要的当前值NUM作为参数。这是不太正确的说法函数的原子被打破 - 因为它是呼叫者的加载从 NUM 价值的责任,这不是部分函数的接口。我同样可以抱怨的:

You see, __sync_fetch_and_add is indeed atomic, but it behaves like an ordinary function -- so it takes the current value of "num" as a parameter. It is not quite correct to say the atomicity of the function is broken -- because it is the responsibility of the caller to load the value from num, and it's not part of the function's interface. I could equally complain about this:

__sync_fetch_and_add(&var, some_really_long_function());

或者更糟的是,

__sync_fetch_and_add(long_function_1(), long_function_2());

您说这可能是因为PTED间$ P $

You say it "may be interpreted as"


  1. 加载变量var的地址

  2. 加载变量num的值

  3. 执行原子除了

但根据到C规格,它不是,它的可能的是PTED这样间$ P $,而是它的必须的是间preTED这方式,否则编译器将不符合的(实际上,它可以交换#1和#2,但在这里,这不是很重要)。

But according to the C spec, it's not that it may be interpreted this way, but rather, it must be interpreted this way, otherwise the compiler would not be conformant (actually, it could swap #1 and #2, but that's not important here).

这篇关于GCC原子内置函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆