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.

classification
Title: Erroneous memory behaviour for objects created in another thread
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: Adria Garriga, peter.otten
Priority: normal Keywords:

Created on 2016-07-08 14:54 by Adria Garriga, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg269988 - (view) Author: Adria Garriga (Adria Garriga) Date: 2016-07-08 14:54
I create several objects in the main thread, and then spawn several threads that "take ownership" of one object each. Within that thread, the objects' attributes' values are not consistent. The bug only happens sometimes.

from threading import Thread
import pdb
n_threads = 8

def f(self):
    self.obj[0] = 0
    t = 0
    while True:
        if t != self.obj[0]:
            pdb.set_trace() # should not happen
        t += 1
        self.obj[0] += 1

for _ in range(n_threads):
    t = Thread(target=lambda: f(t))
    t.obj = [0]
    t.start()


Tested in Python 2.7.11 under Ubuntu 16.04 LTS and OS X. The bug does not happen in Python 3.5 or Python 3.6 .

Attached is a very similar program that exhibits the same issue, but which may be clearer and can sometimes be killed with Ctrl-C.
msg269995 - (view) Author: Peter Otten (peter.otten) * Date: 2016-07-08 16:24
Your code relies on the assumption that when the lambda is invoked the global t is still bound to the Thread instance you are starting. It seems that this is not always the case, and I don't see why it should be guaranteed either.
I don't know whether it's a good idea to store per-thread data in the Thread instance (have a look at threading.local()), but

def start_thread():
    t = Thread(target=lambda: f(t))
    t.obj = [0]
    t.start()

for _ in range(n_threads):
    start_thread()

will at least avoid the global.
msg269996 - (view) Author: Adria Garriga (Adria Garriga) Date: 2016-07-08 16:31
Yes, that seems to be it. Storing info in the Thread object is just for the sake of keeping the example short, but the error is the same you pointed out.

Thank you very much and I hope I didn't waste too much of your time!
History
Date User Action Args
2022-04-11 14:58:33adminsetgithub: 71655
2016-07-08 16:41:42abarrysetresolution: not a bug
stage: resolved
2016-07-08 16:31:32Adria Garrigasetstatus: open -> closed

messages: + msg269996
2016-07-08 16:24:28peter.ottensetnosy: + peter.otten
messages: + msg269995
2016-07-08 14:55:17Adria Garrigasetfiles: - test.py
2016-07-08 14:54:31Adria Garrigacreate