Reputation: 119
import threading
x = 0;
class Thread1(threading.Thread):
def run(self):
global x
for i in range(1,100000):
x = x + 1
class Thread2(threading.Thread):
def run(self):
global x
for i in range(1,100000):
x = x - 1
#create two threads
t1 = Thread1()
t2 = Thread2()
#start the threads
t1.start()
t2.start()
#wait for the threads to finish
t1.join()
t2.join()
print x;
Running this multiple times produces different output, some in the negative and some in the positive. Is it because the two threads are using the same global x? I don't understand why: shouldn't the net effect (output) be the same after all the dust settles?
Upvotes: 1
Views: 385
Reputation: 150977
Not necessarily. Imagine the following sequence of events. We'll begin at a precise moment after the program has been running for a bit; both Thread1
and Thread2
are inside their for
loops, and x = 0
Thread1
has control. It accesses x
to determine the value of x + 1
; x
is 0
, so the result is 1
. However...Thread1
completes the assignment, control passes to Thread2
. x
is still 0
. Thread2
now accesses x
. It calculates x - 1
, which is -1
, because x
is still 0
. Because of the unpredictability of thread timing, it manages to complete the operation, assigning -1
to x
. Thread1
. It has already calculated the value of x + 1
to be 1
. It assigns 1
to x
.Both threads have completed an iteration, and the value of x
should be 0
, but its actual value is 1
.
Upvotes: 3
Reputation: 7102
This is a classic concurrency problem in multithreaded computing. Each thread must read the current value of x from memory, modify it, then write it back. If thread 1 reads the value, then thread 2 updates it, when thread 1 writes the value back it will cancel thread 2's update. This is why you should always use proper synchronisation constructs such as semaphores etc.
Upvotes: 2