Re: volatile is ignored by my compiler?
{ Top-posting converted to bottom-posting by mod.
Please follow the convention in this group. -mod }
On Tuesday, November 17, 2009 6:13:37 PM UTC-8, Joshua Maurice wrote:
On Nov 16, 1:05 pm, "Balog Pal" <p...@lib.hu> wrote:
"Hei" <hchan1...@gmail.com>
My confusion came after I read this article:
http://www.ddj.com/cpp/184403766
Did you actually read it beyond the title?
The better question is did \you\ actually read it beyond the title.
It is about supplementing the code using sync with type system checks.
It neve claims volatile would be a replacement to using mutex and locking.
Yes, it does.
Quoting ddj article
Although both C and C++ Standards are conspicuously silent when it comes to threads, they do make a little concession to multithreading, in the form of the volatile keyword.
Just like its better-known counterpart const, volatile is a type modifier. It's intended to be used in conjunction with variables that are accessed and modified in different threads. Basically, without volatile, either writing multithreaded programs becomes impossible, or the compiler wastes vast optimization opportunities. An explanation is in order.
The article goes on to suggest that the following is a
"correct" (albeit inefficient and slow), condition variable in multi-
threaded situations:
class Gadget
{
public:
void Wait()
{ while (!flag_)
Sleep(1000); // sleeps for 1000 milliseconds
}
void Wakeup() { flag_ = true; }
...
private:
volatile bool flag_;
};
Quote ddj article (in the context of flag_ not being volatile):
Suppose the compiler figures out that Sleep(1000) is a call into an external library that cannot possibly modify the member variable flag_. Then the compiler concludes that it can cache flag_ in a register and use that register instead of accessing the slower on-board memory. This is an excellent optimization for single-threaded code, but in this case, it harms correctness: after you call Wait for some Gadget object, although another thread calls Wakeup, Wait will loop forever. This is because the change of flag_ will not be reflected in the register that caches flag_. The optimization is too ... optimistic. Caching variables in registers is a very valuable optimization that applies most of the time, so it would be a pity to waste it. C and C++ give you the chance to explicitly disable such caching. If you use the volatile modifier on a variable, the compiler won't cache that variable in registers ??? each access will hit the actual memory location of that variable. So al
l
you have to do to make Gadget's Wait/Wakeup combo work is to qualify flag_ appropriately:
[Insert code fragment with volatile flag_]
That piece of code when Wait and Wakeup are called from different
threads, despite whatever volatile qualification, is not correct
according to the C++ standard (as it doesn't mention threads). If it
was correct, that would be against the spirit of the C and C++
standard: (1- Volatile is for memory mapped IO, signal handlers, and
setjump longjump (sp). 2- Cost competitive with assembly. 3- Don't pay
for what you don't use.). It will not be correct in C++0x, which
includes descriptions of threading. Finally, according to the standard
threading library POSIX, it's actually wrong. (However, using the
other standard threading library, win32, the code fragment may be
correct with volatile. Go find a microsoft newsgroup or use the msdn
webpages for further details.)
Sorry to bring back this old thread.
As most of you pointed out, C++ Standard (before C11) doesn't know
anything about thread; hence, volatile has nothing to do with thread.
I just want to understand whether this statement from Modern C++ Design
(by Andrei Alexandrescu) is wrong:
"C++ provides the volatile type modifier, with which you should qualify
each variable that you share with multiple threads."
Although it doesn't explicitly suggest volatile do something about
multithreading, it seems to me that it implicitly suggests so.
If not, how should I interpret the statement?
Thanks in advance.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]