简体   繁体   English

C原子操作,如果写入都是原子交换,我需要原子加载吗?

[英]C atomic operations, if writes are all atomic swaps do I need atomic load?

I am writing a program in C. FOR SIMPLICITY LETS SAY: There are several variables that many threads can both read and write. 我正在用C语言编写一个程序。简单地说:有许多线程可以读写的变量。 Every time one of these is written it is written via an atomic swap (GCC atomic operations, sync and swap). 每次写入其中一个时,它都是通过原子交换(GCC原子操作,同步和交换)编写的。 Do I need to use an atomic load every time I read one of these variables, or are the atomic writes sufficient to avoid reading in data mid-write? 每次读取其中一个变量时,是否需要使用原子加载,或者原子写入是否足以避免在写入中读取数据?

Note, anywhere that needs to use data from one of these vars first copies the value: 请注意,任何需要使用其中一个变量的数据的人都会首先复制该值:

int success = 0;
while ( !success ) {
  int x = shared_x;
  ... work with x, result in y ...
  success = cmp_swap( &shared_x, x, y );
}

My question is not about a data race, that is I am not concerned I might loose data. 我的问题不是关于数据竞争,我不担心我可能会丢失数据。 MY concern is that the value of shared_x might change halfway through my reading it. 我担心的是,在阅读它之后,shared_x的价值可能会发生变化。 Say it is an 8-byte integer, would this be a potential problem: say shared_x is a 64-bit integer, 8 bytes. 假设它是一个8字节的整数,这是一个潜在的问题:比如说shared_x是一个64位整数,8个字节。 Would it be possible that my x = shared_x will copy the first 4 bytes, then something atomically writes to shared_x, then this statement finishes reading the second 4 bytes. 我的x = shared_x是否可能复制前4个字节,然后原子地写入shared_x,然后此语句完成读取后4个字节。 This would result in x containing the first 4 bytes of an old value of shared_x, and the last 4 bytes of the new shared_x. 这将导致x包含旧值shared_x的前4个字节,以及新shared_x的最后4个字节。 I suspect the memory barrier in the atomic swap ( http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html - using __sync_bool_compare_and_swap) is enough to protect against this... but I am not sure. 我怀疑原子交换中的内存障碍( http://gcc.gnu.org/onlinedocs/gcc-4.1.1/gcc/Atomic-Builtins.html-使用__sync_bool_compare_and_swap)足以防止这种情况......但我我不确定。

It looks like you're reading from shared_x , calculate something new and then write back to shared_x . 看起来你正在读取shared_x ,计算新的东西,然后回shared_x The value you write to shared_x seems to depend on the value you originally read from it. 您写入shared_x的值似乎取决于您最初从中读取的值。

If that is the case, you have a dependency there, and most probably need to not only make the read atomic, but you need to make the whole operation of "read, calculate, write back" atomic. 如果是这种情况,那么你就有了一个依赖,并且很可能不仅需要使读取原子,而且需要使“读取,计算,回写”的整个操作成为原子。 Meaning, you need to synchronize it. 意思是,您需要同步它。 Like with a mutex. 就像互斥体一样。

I say "most probably" because I can't be sure if I don't know what the code actually does. 我说“最有可能”,因为我无法确定我是否不知道代码实际上做了什么。 You need to analyze what happens in the case of a race condition where thread A writes to shared_x while thread B is currently doing a calculation based on the old value of shared_x and then writes the result back to it. 您需要分析在竞争条件下发生的情况,其中线程A写入shared_x而线程B当前正在基于shared_x的旧值进行shared_x ,然后将结果写回给它。 The value written to it by thread A gets lost forever. 线程A写入它的值永远丢失。 I can't know whether this would be problematic for you. 我不知道这对你来说是否有问题。 Only you can know that. 只有你能知道。 If that race condition is OK, then you don't need to synchronize or make the read atomic. 如果该竞争条件正常,则您不需要同步或使读取原子。

If you're only interested in making sure that reading from shared_x will not get you garbage and don't care about the race condition described above, then the answer is "most probably you don't need to make the read atomic." 如果你只是想确保从shared_x读取不会让你变得垃圾并且不关心上面描述的竞争条件,那么答案是“很可能你不需要读取原子”。 Instead of me copy&pasting, you can read the details right here: 而不是我复制和粘贴,你可以在这里阅读详细信息:

Atomicity in C++ : Myth or Reality C ++中的原子性:神话还是现实

Even though the question is for C++, the same holds true for C as well. 即使问题是针对C ++,C也是如此。

Note though that atomics are now in the C standard as well (C11), provided by the <stdatomic.h> header and the _Atomic type qualifier. 注意尽管这原子公司现在在C标准以及(C11),通过所提供的<stdatomic.h>头和_Atomic类型限定符。 But of course not all compilers support C11 yet. 但当然并非所有编译器都支持C11。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM