Need to use "volatile" for accessing variables between threads?
Let's say I have a global variable:
int g_counter;
And let's say that this variable is accessed by two different threads.
Here's how the threads might look:
void Thread_One(void)
{
for (;;)
{
if ( !DoSomethingThatTakes15seconds() )
++g_counter;
}
}
void Thread_Two(void)
{
for (;;)
{
if ( DoSomethingThatTakes5seconds() )
--g_counter;
}
}
We need a mutex though. So the second draft would be:
void Thread_One(void)
{
for (;;)
{
if ( !DoSomething() )
{
LockMutex();
++g_counter;
UnlockMutex();
}
}
}
void Thread_Two(void)
{
for (;;)
{
if ( !DoSomething() )
{
LockMutex();
++g_counter;
UnlockMutex();
}
}
}
Finally though, I'd like to clarify one thing:
Do I need to define the g_counter as volatile? I realise that volatile
is intended to be used where the value of a variable can spontaneously
change outside of the normal flow of a program, but I don't know if
this applies to multi-threading.
I'm currently writing cross-platform software which is to be compiled
for different systems such as Windows, Linux, Solaris, Apple Mac.
These different systems have different API's for doing multi-
threading, and maybe each particular API should specify whether global
variables need to be volatile or not. (Or should it be considered
something inherent in the programming language?)
Now the thing is, I'm using the threading library that comes with
wxWidgets. (wxWidgets is a cross-platform library for creating GUI
programs in C++). Within the wxWidgets manual, I can't see anything
about the volatile keyword, so I don't know whether it's needed or
not.
To play it safe, I suppose I could just go and use the volatile
keyword and be done with it. However, this adds a very inconvenient
complication. Let's say I have a global array as follows:
int volatile figures[50];
Inside the code for one of the threads, I might add 7 to every element
of this array:
int const *const pend = figures + (sizeof figures / sizeof
*figures);
for (int *p = figures; figures != pend; ++figures)
*p += 7;
Now the problem here is that this won't compiler, reason being that I
have to tag "volatile" onto all of the pointer definitions. That's a
pain in the ass. (I did it before in a previous C program but it was
quite annoying).
What's the way to go about this? I have some people telling me there's
no need for volatile at all when it comes to multi-threading.