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
withdraw
in thread A, A2 means OS execute the second line of functionwithdraw
in thread A, B3 means OS execute the third line of functionwithdraw
in 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 restorebalance
to 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.