I have a multi-threaded C++ application.
Now I know that for global shared variables, you should use volatile in some cases while checking the state of the variable or else the compiler could assume that the variable's value never changes (in that thread).
What if, however, instead of checking the status of a variable I call a method that returns the value of the variable? For instance:
static int num = 0;
...
void foo()
{
while(getNum() == 0)
{
// do something (or nothing)
}
}
Would I still have to make num a volatile variable? or does the compiler recognize that since I'm using a method to access that variable num it won't cache the result?
Anyone got any ideas?
Thanks in advance,
~Julian
edit: inside my while loop I removed the sleep call and replaced it with something generic such as a comment to do something (or nothing)
No, volatile
is never needed as long as you're doing the necessary synchronization.
Calling thread library synchronization functions, whatever they are on your platform, should take care of invalidating locally "cached" values and making the compiler reloads globals.
In this particular case, sleep
is likely to have such an effect, but it's not a good implementation anyway. There should be a condition variable on num
, protect it with a setter function, and have the setter function send a signal to foo
.
As to the specific question, whether the function hides the access from optimization is extremely implementation- and situation-dependent. Your best bet is to compile the getter function in a separate invokation of the compiler, but even then, there's no way to guarantee that interprocedural optimization doesn't occur. For example, some platforms may put IR code in the .o
files and perform code generation in the "linker" stage.
Key words above: 1. as long as you're doing the necessary synchronization and 2. likely to have such an effect.
1: sleep
or an empty busy-loop are not "necessary synchronization." That is not the correct way to write a multithreaded program, period. So, volatile may be needed in such cases.
2: Yes, sleep
may not be counted by the implementation an I/O function, and may even be labeled as pure and free of side-effects. In that case, volatile
on the global would be necessary. However, I doubt any implementations have really been distributed which would break sleep
loops like that, since they are unfortunately common.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With