how and when shoud I use volatile keyword?

Started by
12 comments, last by Yann L 12 years, 11 months ago
suppose i have this code

[source]
class Thread
{
public:
void PostQuitSignal()
{
quit_ = true;
}

Desc GetDesc()
{
return desc_;
}

private:
void ThreadLoop()
{
while (!quit_)
{
//do other main thread logic like read message queues etc
}
}

bool quit_; //does this need to be volatile??
Desc desc_; //this struct is magically initialize with all values at constructor and never changes anymore, does this need to be volatile too??
};
[/source]

suppose in a mulithread app, the above class when started will run ThreadLoop function. Does the variable "quit_" and "desc_" need to be volatile??

regards
Advertisement
`quit_' should definitely be volatile. Otherwise the compiler might optimize the `while (!quit_)' loop, if it can determine that `quit_' can't possibly be changed by the code inside the loop.
That's a misuse of the volatile keyword.

The volatile keyword is aimed at I/O, not multiprocessing. While it may work for your particular hardware and compiler, the only guarantees you have with volatile are that it won't get optimized out or reordered. It does not provide any guarantees about multiprocessing environments. Volatile variables provide no guarantees about cache coherence or memory boundaries, so it has no guarantee for usefulness between threads. Just because it is not optimized out does not mean it will be shared between threads or processors in the way you are expecting.

This is not what you want. What you are looking for is a multiprocessing flag or other IPC to indicate your status.


Choose the right tool for the job.

Use a semaphore or other communication function provided by your multiprocessing library, not a volatile variable.
Hmmm... I've used `volatile' before for this purpose and it worked fine, but I will be happy to use a more specific tool to get the job done if one is available.

Using a semaphore for a variable that will only be changed by the main thread seems expensive and unnecessary. What is an example of "flag function" (with POSIX threads of Boost.Thread, for instance)?
This document that I was recently linked to has helped me understand the Volatile keyword better.

Click Here

Hmmm... I've used `volatile' before for this purpose and it worked fine, but I will be happy to use a more specific tool to get the job done if one is available.

Using a semaphore for a variable that will only be changed by the main thread seems expensive and unnecessary. What is an example of "flag function" (with POSIX threads of Boost.Thread, for instance)?


Just because it happened to work for you doesn't mean it is the right way to do it. As mentioned, volatile provides absolutely no guarantees about cache coherency or memory barriers. While your system might have happened to do this work for you, you had no guarantee that it would, nor do you have any guarantees that other systems will do it.


Boost cut their Semaphore class because people were misusing it for communication; use a condition variable instead.


Visual C++ has actually implemented additional pessimizations when you use volatile keyword because people misuse the keyword as you described. On that system use InterlockedIncrement to set your flag and ensure it will be immediately propagate beyond the original thread and across multiple processors.
hi, @frob, what libraries do you suggest I use?? I am currently using most stuff from boost threads.

lastly i am using gcc4.6 so I have access to std::atomic, but i did not use it as I thought writing and reading a bool is guarantee to be atomic?

regards
hi, @ frob, I don't understand how to use boost.conditional_variable to replace the quit variable. As in this case, the quit_ variable is use as a flag by the thread to determine if it need to terminate, if not it continue processing its stuff. However wouldn't boost.conditional_variable cause the said thread to sleep or block when the condition is not met?

regards

[quote name='alvaro' timestamp='1304349607' post='4805482']
Hmmm... I've used `volatile' before for this purpose and it worked fine, but I will be happy to use a more specific tool to get the job done if one is available.


Just because it happened to work for you doesn't mean it is the right way to do it.[/quote]

I didn't claim that it was the right way to do it, and I thought I showed a good disposition to learn the right way to do it. I am still trying to learn, not trying to fight you.

Condition variables seem to block until something happens. I don't see a need for that in the situation we are talking about. We just want the child thread to go about its business until someone sets the quit_ flag. Whenever it sees that flag has been set, it will quit, and presumably the main thread will be waiting for this to happen, using join.

So could you please provide some code showing how to do this with some multithreading library? POSIX threads and Boost.Thread are the two I have used before, so it would be great if you could write it using one of those.

lastly i am using gcc4.6 so I have access to std::atomic, but i did not use it as I thought writing and reading a bool is guarantee to be atomic?


C++ has no guarantees that reading or writing are ever atomic or synchronized, not even for bool values.

This topic is closed to new replies.

Advertisement