Let's say I have a global variable called "monkey":
int monkey;
And let's that I have two different threads that need to access this variable. Of course, I'm gonna create a wxCriticalSection and do p_critical_section_monkey->Enter() before I access it.
My question though is whether I need to define "monkey" as volatile? E.g.:
int volatile monkey;
Any need for "volatile" when accessing stuff btwn
-
- I live to help wx-kind
- Posts: 172
- Joined: Sun Sep 07, 2008 9:49 pm
- Location: Rio de Janeiro, Brazil
The volatile keyword is used to avoid compilers optimizing reads from the memory where the variable is stored.
For example:
In this code, g_int will be evaluated only once (i.e. the memory will be read outside the loop.) If you need it to be evaluated every time it's added to a, you have to declare it as volatile.
You shouldn't need to use volatile in your case. Access to shared variables should be surrounded by mutexes because you cannot guarantee that the read/write will be atomic and the value can come up with garbage.
If you use atomic operations, you can probably avoid the use of mutexes to read/write shared variables.
Cheers,
Andre
For example:
Code: Select all
int g_int;
...
for (i = 0; i < 100; i++)
a += g_int;
You shouldn't need to use volatile in your case. Access to shared variables should be surrounded by mutexes because you cannot guarantee that the read/write will be atomic and the value can come up with garbage.
If you use atomic operations, you can probably avoid the use of mutexes to read/write shared variables.
Cheers,
Andre
The reason I asked, is that "volatile" is intended to be used in circumstances where the value of a variable may change spontaneously outside the normal flow of a program. Because its value may spontaneously change, the variable's value should never be cached, it should always be read straight from memory.
If you have two threads accessing the same variable, you could say that one thread would observe a spontaneous change in the variable's value.
For example, here's one particular explanation of "volatile" which I found on the MSDN website:
"The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread."
I had a look through the manual for multithreading in wxWidgets, but couldn't find any mention of the "volatile" keyword.
Are you 100% certain that I'm safe to declare a global variable as non-volatile, and then go on to edit its value in more than one thread? (Of course I'd use a wxCriticalSection before editing or reading the value).
I think the manual for multi-threading should clarify this.
If you have two threads accessing the same variable, you could say that one thread would observe a spontaneous change in the variable's value.
For example, here's one particular explanation of "volatile" which I found on the MSDN website:
"The volatile keyword is a type qualifier used to declare that an object can be modified in the program by something such as the operating system, the hardware, or a concurrently executing thread."
I had a look through the manual for multithreading in wxWidgets, but couldn't find any mention of the "volatile" keyword.
Are you 100% certain that I'm safe to declare a global variable as non-volatile, and then go on to edit its value in more than one thread? (Of course I'd use a wxCriticalSection before editing or reading the value).
I think the manual for multi-threading should clarify this.
i think in your case you need the volatile keyword.
As leiradella pointed out, important is what kind of optimizations the compiler performs. If the compiler creates code that evaluates the content of a variable only once and then re-uses it later in the code, even using a mutex won't help.
As leiradella pointed out, important is what kind of optimizations the compiler performs. If the compiler creates code that evaluates the content of a variable only once and then re-uses it later in the code, even using a mutex won't help.
this is not a wxWidgets-specific issue.I think the manual for multi-threading should clarify this.
Use the source, Luke!
-
- I live to help wx-kind
- Posts: 172
- Joined: Sun Sep 07, 2008 9:49 pm
- Location: Rio de Janeiro, Brazil
But you still need to make sure you read/write the variable only with atomic operations. Take a look at http://msdn.microsoft.com/en-us/library ... 85%29.aspx.doublemax wrote:i think in your case you need the volatile keyword.
32-bit reads and writes on 32-bit aligned variables are guaranteed to be atomic on x86 because the bus is also 32-bit. The compiler also ensures proper alignment. But if you're going to read/write 64-bit on a 32-bit processor, you have to use one of the intrinsics to ensure atomic operations.
Also, take note that if you're going to, for example, read, increment and write, you'll have to make all three operations atomic. In this case, use a mutex around that code or one of the intrinsics.
Cheers,
Andre
OK I got the answers I needed. It turns out that I don't need volatile. There's a short discussion of it here:
http://groups.google.ie/group/comp.lang ... 929c344d4/
Also regarding the atomic thing with 32-Bit integers, well that's a no-no as well. I can't remember exactly why, but it's something to do with memory barriers or something like that (CPU cache is involved as far as I know).
http://groups.google.ie/group/comp.lang ... 929c344d4/
Also regarding the atomic thing with 32-Bit integers, well that's a no-no as well. I can't remember exactly why, but it's something to do with memory barriers or something like that (CPU cache is involved as far as I know).
-
- I live to help wx-kind
- Posts: 172
- Joined: Sun Sep 07, 2008 9:49 pm
- Location: Rio de Janeiro, Brazil
Maybe it's an issue with multi-core architectures, I don't know. But then again, the intrinsics should ensure you atomic operations regardless of the specific architecture. Or use mutexes.Virchanza wrote:Also regarding the atomic thing with 32-Bit integers, well that's a no-no as well. I can't remember exactly why, but it's something to do with memory barriers or something like that (CPU cache is involved as far as I know).
Cheers,
Andre