Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why 2 threads incrementing one variable can result in different outputs

I just started learning concurrent programming, and even though I have a vague idea about this, why can two threads incrementing one variable result in different outputs?

Let's say the variable i is global, and there are two threads trying to do

i = i + 1;

Why can the output be either 1 or 2? And assuming the main thread doesn't quit, because I know that it is possible that sometimes the main thread quits before one of the threads is able to do anything.

like image 331
PTN Avatar asked Feb 18 '26 17:02

PTN


1 Answers

Because addition operation is not atomic.

From wikipedia:

In concurrent programming, an operation (or set of operations) is atomic if it appears to the rest of the system to occur instantaneously.

Atomicity is a guarantee of isolation from concurrent processes.

Keeping that in mind, consider the following (simplified) illustration. The operation i = i + 1 is made up of three atomic operations:

  • read the current value of i from the memory
  • add 1 to the value that was read
  • write i back to memory

When two threads try to perform i = i + 1, they may both get the same current value of i, and then set it to i + 1, making it appear that only 1 was incremented. Consider the following 2 possible scenarios:

Scenario 1

int i = 0;
i = i + 1;

Thread 1: Reads i       // Reads 0
Thread 1 : i = i + 1    // Adds 1 to i
Thread 1: Write i = 1   // Makes i == 1
Thread 2: Reads i;      // Reads 1
Thread 2: i = i + 1     // Adds 1 to i, making i == 2
Thread 2: Write i = 2   // Makes i == 2

// Finally, i becomes 2

In the above scenario, everything works as expected. But what happens when Thread 2 reads before Thread 1 writes the value of i?

Scenario 2

int i = 0;
i = i + 1;

Thread 1: Reads i       // Reads 0
Thread 1 : i = i + 1    // Adds 1 to i
Thread 2: Reads i;      // Reads 0 - NOT 1 because it's not written to memory yet
Thread 1: Write i = 1   // Makes i == 1
Thread 2: i = i + 1     // Adds 1 to i, making i == 1 (Remember, thread 2 had read 0)
Thread 2: Write i = 1   // Makes i == 1

// i is finally 1, instead of 2
like image 108
John Bupit Avatar answered Feb 21 '26 09:02

John Bupit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!