I have been confused at this question:
I have C++ function:
void withdraw(int x) {
balance = balance - x;
}
balance is a global integer variable, which equals to 100 at the start.
We run the above function with two different thread: thread A and thread B. Thread A run withdraw(50) and thread B run withdraw(30).
Assuming we don't protect balance, what is the final result of balance after running those threads in following sequences?
- A1->A2->A3->B1->B2->B3
- B1->B2->B3->A1->A2->A3
- A1->A2->B1->B2->B3->A3
- B1->B2->A1->A2->A3->B3
Explanation:
A1 means OS execute the first line of function
withdrawin thread A, A2 means OS execute the second line of functionwithdrawin thread A, B3 means OS execute the third line of functionwithdrawin thread B, and so on.The sequence is how OS schedule thread A & B presumably.
My answer is
- 20
- 20
- 50 (Before context switch, OS saves
balance. After context switch, OS restorebalanceto 50) - 70 (Similar to above)
But my friend disagrees, he said that balance was a global variable. Thus it is not saved in stack, so it does not affected by context switching. He claimed that all 4 sequences result in 20.
So who is right? I can't find fault in his logic.
(We assume we have one processor that can only execute one thread at a time)
Simple and short answer for c++: Unsynchronized access to a shared variable is undefined behavior, so anything can happen. The value can e.g. be 100,70,50,20,42 or -458995. The program could crash or not. And in theory its even allowed to order pizza.
The actual machine code that is executed is usually far away from what your program looks like and in the case of undefined behavior, you are no longer guaranteed, that the actual behavior has anything to do with the c++ code you have written.