5

How can I be sure this code is thread safe ?

import numpy as np
from threading import Thread

n_threads = 5

ones = np.ones((5, 5))
A = np.ones((5, 5))

def my_function():
    global A
    for i in range(250):
        A += ones # is += thread safe ?

threads = [Thread(target=my_function) for i in range(n_threads)]

for t in threads:
    t.start()

for t in threads:
    t.join()

print(A)

Should A be a critical shared memory ? Surprisingly I always get the same result, and all entries of the array all have the same value. I would expect for the threads to update the values of the matrix, and for some to be lost...

Thanks.

5
  • In my opinion, it is not safe even within one thread. When the array has "many" rows (whatever "many" means), they are often updated in blocks, so if if you do a+=a[0], the a[0] may change as you go. Commented Sep 3, 2017 at 23:15
  • 1
    @DYZ: They actually introduced defined semantics for operations like that in 1.13, the newest release. Commented Sep 3, 2017 at 23:21
  • 1
    While the GIL does provide some level of protection for operations like this on CPython, there are still cases where it fails, and other Python implementations (some of which do have some level of support for NumPy) may do no locking or finer-grained locking. Commented Sep 3, 2017 at 23:24
  • += is not useful if you expect to add values repeatedly to an indexed value. It uses a buffer. See add.at for an unbuffered version. Commented Sep 4, 2017 at 0:03
  • Thanks for the clarification. Commented Sep 4, 2017 at 12:19

1 Answer 1

3

Your code is not safe. Some NumPy ufuncs (like add() which you implicitly use) can release the GIL. Probably the reason you never see any problems in your toy example is that it runs for such a short time and the data size is very small. You may also be avoiding problems by the simple nature of your calculation, but I imagine your real code is more complex.

In short, you can't do what you're doing in multiple threads without locking. And locking will probably defeat the purpose of multiple threads for code like this.

Sign up to request clarification or add additional context in comments.

1 Comment

Sure, you're right. I've increased the matrix size to 1000, and 1000 iterations and the issue came up. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.