Operator increment atomicity

I was told in an interview that in C, using the ++ operator (say, I ++), an atomic operation is performed, say, "i + = 1" - no. I thought these operations were exactly the same when it comes to thread safety or atomicity. Am I missing something or are they really different?

+6
source share
3 answers

This is nonsense. Any of them may or may not be atomic, depending on the type of data, architecture and, possibly, the compiler (the standard does not give any guarantees regarding atomicity at all if you do not use C11 atomization), but I see no reason to think that, generally speaking, i++ will be atomic if i += 1 not. It is very likely that they actually generate the same code in a context where the result of the expression is not used.

+10
source

Operators * i++; and i += 1; are equivalent in C. None of them are guaranteed to be atomic.

In particular, increments of variables that exceed the size of the system word (for example, 64-bit variables in 32-bit systems) are almost always non-atomic, since increment of such a variable atomically often requires explicit blocking. In addition, some architectures do not support the direct expansion of variables in memory. (That is, they require an explicit load / modify / save sequence.) These architectures cannot atomically modify any variable without locking.

* if viewed as standalone operators, not expressions

+8
source

the interviewer is wrong.

I compiled two functions with gcc-4.8.2 -O2 -S

 void increment1(int *a) { *a += 1; } void increment2(int *a) { (*a)++; } 

both generate exactly the same assembly

 increment1: .LFB0: .cfi_startproc addl $1, (%rdi) ret .cfi_endproc .LFE0: .size increment1, .-increment1 .p2align 4,,15 .globl increment2 .type increment2, @function increment2: .LFB1: .cfi_startproc addl $1, (%rdi) ret .cfi_endproc 

But in the context of a more precise technical tarm, both of them are atomic write , which means that it does not provide a MAD result. if you use the int64_t variable in a 32-bit or less processor bit environment, the 64-bit modification causes multiple writes. It cannot be atomic write without locking.

You can use the __sync_fetch_and_add(&a, 1) operation to __sync_fetch_and_add(&a, 1) increment in gcc environment.

+2
source

Source: https://habr.com/ru/post/981091/


All Articles