views:

87

answers:

2

If I have the following psuedocode:

sharedVariable = somevalue;
CreateThread(threadWhichUsesSharedVariable);

Is it theoretically possible for a multicore CPU to execute code in threadWhichUsesSharedVariable() which reads the value of sharedVariable before the parent thread writes to it? For full theoretical avoidance of even the remote possibility of a race condition, should the code look like this instead:

sharedVariableMutex.lock();
sharedVariable = somevalue;
sharedVariableMutex.unlock();
CreateThread(threadWhichUsesSharedVariable);

Basically I want to know if the spawning of a thread explicitly linearizes the CPU at that point, and is guaranteed to do so.

I know that the overhead of thread creation probably takes enough time that this would never matter in practice, but the perfectionist in me is afraid of the theoretical race condition. In extreme conditions, where some threads or cores might be severely lagged and others are running fast and efficiently, I can imagine that it might be remotely possible for the order of execution (or memory access) to be reversed unless there was a lock.

+1  A: 

Given your example and if you were using Java then the answer would be "No". In Java it is not possible for the thread to spawn and read your value before the assignment operation is complete. In some other languages this might be a different story.

"Variables shared between multiple threads (e.g., instance variables of objects) have atomic assignment guaranteed by the Java language specification for all data types except longs and doubles... If a method consists solely of a single variable access or assignment, there is no need to make it synchronized for thread-safety, and every reason not to do so for performance." reference

If your double or long is declared volatile, then you are also guaranteed that the assignment is an atomic operation.

Update: Your example is going to work in C++ just like it works in Java. Theoretically there is no way that the thread spawning will begin or complete before the assignment, even with Out of Order Execution.

Note that your example is VERY specific and in any other case it is recommended that you ensure the shared resource is protected properly. The new C++ standard is coming out with a lot of atomic stuff, so you could declare your variable as atomic and the assignment operation will be visible to all threads without the need of locking. CAS (compare and set) is a your next best option.

Lirik
Thanks for your answer, but I was really asking about C++ (or any language which puts you close to the machine level) and should have said so. I'll add a comment clarifying my question.
Deadcode
Thank you Lirik, and Per, both your answers have been helpful.
Deadcode
+2  A: 

I would say that your pseudocode is safe on any correctly functioning multiprocessor system. The C++ compiler cannot generate a call to CreateThread() before sharedVariable has received a correct value unless it can prove to itself that doing so is safe. You are guaranteed that your single-threaded code executes equivalently to a completely non-reordered linear execution path. Any system that "time warps" the thread creation ahead of the variable assignment is seriously broken.

I don't think declaring sharedVariable as volatile does anything useful in this case.

Per Ekman