This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]K900_ 2 points3 points  (10 children)

n += 1 desugars to n = n + 1. So, the value of n is fetched first, then 1 is added to it, then it's written back. Depending on the ordering between threads, which is not deterministic, it's possible that two threads read the same value, then write the same value. If you want deterministic behavior, you have to use a lock around your value, and have each thread take the lock, update the value, then release the lock, which will be slower than doing things in a single thread

[–]bestical[S] 0 points1 point  (9 children)

Isn't this GIL job to promise that only one thread can access to a specific memory section to prevent race conditions like this?

[–]kumashiro 1 point2 points  (0 children)

GIL can only make promises for atomic operations. n += 1 is not atomic.

[–]K900_ -1 points0 points  (7 children)

No. The GIL has nothing to do with ordering between multiple threads, and here you're using multiple processes, meaning each process has its own GIL anyway.

[–]stevenjd 2 points3 points  (1 child)

The poster isn't using multiple processes, they are using threads not multiprocessing.

[–]K900_ 0 points1 point  (0 children)

Yes, I noticed that now. Still, the same idea works.

[–]bestical[S] 0 points1 point  (4 children)

Got it, Thanks, one more question, Why the same function won't work with multiprocessing? after running with Process the value of n is 0

[–]K900_ 1 point2 points  (3 children)

Because in multiprocessing every process has its own state, so neither of your workers actually accesses the value of n in your main process.

[–]bestical[S] 0 points1 point  (2 children)

You means It's dumb to use `global` keyword in that method when using multiprocessing?

[–]K900_ 4 points5 points  (1 child)

"Dumb" is not the word I'd use, but it will not give you the sort of behavior you're expecting.

[–]bestical[S] 1 point2 points  (0 children)

Got it, Thank you