Tim Peters <[email protected]> added the comment:
Serhiy, we haven't documented such stuff, and, indeed, I've been burned by it
but much more often in the case of multiprocessing.Process. But note that I'm
SWAPPING the order of your last two lines. In the original, you mutated the
argument _before_ starting any parallel work, so "of course" the new worker
will see the mutation:
def access(xs):
print(xs)
args = ([1],)
t = multiprocessing.Process(target=access, args=args)
t.start() # start parallel work before mutating
args[0][0] = 2
Does that print [1] or [2]? Passing a tuple in no way prevents mutations to
mutable objects the tuple contains.
When the docs are silent, "implementation defined" rules. Whether you use
threading or multiprocessing in the altered example above, the result printed
simply isn't defined - it's a race between the main thread doing the mutation
and the "parallel part" accessing the mutated object.
This is subtler in the multiprocessing context, though, because the relevant
"parallel part" is really the hidden thread that pickles the argument list to
send to the worker. That effectively makes a deep copy. But it's still a race,
just not one visible from staring at the Python code. In the threading case, no
copies are made.
----------
_______________________________________
Python tracker <[email protected]>
<https://bugs.python.org/issue45735>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com