0

Hi i wrote a code recently with following skeleton :

variable;

callback(){
//variable updated here
}

thread_function(){
//variable used
}

main(){
//callback registered
//thread registered
}

I found that whenever the variable is updated at callback, its automatically updated in the thread without declaring the variable as a volatile. well, I am not clear how it is managed. thank you in advance. between, callback() is called from a library being compiled with the code.

Akhil
  • 105
  • 1
  • 8
  • Possible duplicate of [C++ Concurrent modification and read of a single global variable](http://stackoverflow.com/questions/32819166/c-concurrent-modification-and-read-of-a-single-global-variable) – Maxim Egorushkin Oct 01 '15 at 07:37
  • 2
    This C question cannot be a duplicate of a C++ question. The two languages are attempting to coordinate their official multithreading semantics, but they're inevitably specified a little differently. – Potatoswatter Oct 01 '15 at 07:40
  • Possible duplicate of [Why is volatile needed in C?](http://stackoverflow.com/questions/246127/why-is-volatile-needed-in-c) – Bo Persson Oct 01 '15 at 09:01

1 Answers1

6

Ok, first of all, it is broken. You're just lucky your compiler created code that, by accident, seems to work (or maybe unlucky, because it could hide subtle bugs in corner cases).

I found that whenever the variable is updated at callback, its automatically updated in the thread without declaring the variable as a volatile. well, I am not clear how it is managed.

Starting from here: It is one and the same variable. Threads share the same address space. So, this is what you would naively expect.

volatile is about optimizations. A C compiler is free to do a lot of modifications to your code in order to make it faster, this includes reordering of statements, not reading an accessed variable because the same value is in a register, even "unrolling" loops and a lot more. Normally, the only restriction is that the observable behavior stays the same (google for it, I don't want to write a book here.)

Reading a variable from normal memory does not create any side effects, so it can be legally left out without changing behavior. C (prior to ) does not know about threads. If a variable was not written to in some part of code, it is assumed to hold the same value as before.

Now, what volatile gives you is telling the compiler this is not normal memory but a location that could change outside of the control of your program (like e.g. a memory mapped I/O register). With volatile, the compiler is obliged to actually fetch the variable for any read operation and to actually store it for any write operation. It's also not allowed to reorder accesses between several volatile variables. But that's all and it is not enough for synchronizing threads. For that, you also need the guarantee that no other memory accesses or code execution is reordered around accesses of your variable, even with multi-processors -> you need a memory barrier.

Note this is different from e.g. where volatile gives you what you need for thread synchronization. In , use what the pthreads library gives you: mutexes, semaphores and condition variables.

tl;dr

Your code works correctly by accident. In , volatile for threads is wrong (and unnecessary), use synchronization primitives as provided by pthreads.

  • 1
    "`volatile` for threads is wrong" -- Isn't that a bit exaggerated? I think in many simple cases you can get away with just `volatile` variables to signal something from one thread to the other. – undur_gongor Oct 01 '15 at 07:46
  • No, it's always wrong. It introduces guarantees you don't need while leaving the important ones out. Yes, with volatile you can be sure that *eventually* in your code, the change is noticed. You don't get exact synchronization. Just do it right in any case... –  Oct 01 '15 at 07:47
  • 1
    @undur_gongor I'm proposing such *strict rules* because it's 1.) hard to tell for sure whether a sloppy volatile here and there will *really* do in your case and 2.) create bad habits coding and ultimately give wrong ideas about what `volatile` does in C. –  Oct 01 '15 at 07:50