Now I am preparing a report on the topic of synchronization primitives in threads and I am trying to find a good example when one result is obtained with the Lock() blocking, and completely different without using it.
In the example below, I'm trying to increment a number by 1 in a loop on multiple threads at once. I have already brought the number of iterations to 1000000 and the number of threads to 1000, but the effect of race conditions (or whatever else) does not want to occur. The result is still strictly equal to the product of the number of iterations and the number of threads (running on Ubuntu-20.04)
from threading import Thread
COUNT = 1000000
NUM_THREADS = 1000
counter = 0
def increment():
global counter
for _ in range(COUNT):
counter += 1
threads = [Thread(target=increment) for _ in range(NUM_THREADS)]
[thread.start() for thread in threads]
[thread.join() for thread in threads]
diff = counter - COUNT * NUM_THREADS
print(f"Diff for counter without synchronization: {diff}")
Can anyone suggest an example (preferably not very complex) where the result of multiple threads computations without applying synchronization primitives would be different from its "synchronized counterpart"?