1

I'm learning about concurrent programming with Python.

In the following code, I seem to be having synchronizing issues. How can I fix it?

import threading
N = 1000000
counter = 0

def increment():
    global counter
    for i in range(N):
        counter += 1

t1 = threading.Thread(target=increment)
t2 = threading.Thread(target=increment)

t1.start()
t2.start()
t1.join()
t2.join()

print(counter)
TheRealFakeNews
  • 7,512
  • 16
  • 73
  • 114
  • Please read and follow the posting guidelines in the help documentation, as suggested when you created this account. [Minimal, complete, verifiable example](http://stackoverflow.com/help/mcve) applies here. We cannot effectively help you until you post your MCVE code and accurately describe the problem. We should be able to paste your posted code into a text file and reproduce the problem you described. What are the "synchronizing issues"? – Prune Oct 12 '18 at 00:12
  • Possible duplicate of [Python, counter atomic increment](https://stackoverflow.com/questions/23547604/python-counter-atomic-increment) – khachik Oct 12 '18 at 00:19

1 Answers1

1

Both threads are trying to modify counter at the same time, and sometimes they do. That results in some of the increments not appearing. Here is a simple minded approach to solve that problem using threading.Lock:

import threading

N = 1000000
counter = 0

def increment(theLock):
    global counter
    for i in range(N):
        theLock.acquire()
        counter += 1
        theLock.release()

lock = threading.Lock()
t1 = threading.Thread(target=increment, args=[lock,])
t2 = threading.Thread(target=increment, args=[lock,])

t1.start()
t2.start()
t1.join()
t2.join()

print(counter)

The theLock.acquire() and theLock.release() surround code that must be protected to only run in one thread at a time. In your example the acquire and release could also surround the entire loop, but that would be the same as not using multiprocessing. See the threading documentation and in particular, the Lock Objects section.

John Anderson
  • 35,991
  • 4
  • 13
  • 36