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)
Unless the threading standard you are using specifies, then there's no way to know. Most typical threading standards don't, so typically there's no way to know.
Your answer sounds like nonsense though. The OS has no idea what
balanceis nor any way to do anything to it around a context switch. Also, threads can run at the same time without context switches.Your friend's answer also sounds like nonsense. How does he know that it won't be cached in a register by the compiler and thus some of the modifications will stomp on previous ones?
But the point is, both of you are just guessing about what might happen to happen. If you want to answer this usefully, you have to talk about what is guaranteed to happen.