This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author tim.peters
Recipients docs@python, rhettinger, serhiy.storchaka, tim.peters
Date 2021-11-06.16:58:17
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1636217897.75.0.735805262347.issue45735@roundup.psfhosted.org>
In-reply-to
Content
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.
History
Date User Action Args
2021-11-06 16:58:17tim.peterssetrecipients: + tim.peters, rhettinger, docs@python, serhiy.storchaka
2021-11-06 16:58:17tim.peterssetmessageid: <1636217897.75.0.735805262347.issue45735@roundup.psfhosted.org>
2021-11-06 16:58:17tim.peterslinkissue45735 messages
2021-11-06 16:58:17tim.peterscreate