Leekin
Leekin

Reputation: 113

Is id() returns the actual memory address in CPython?

When use id() to get identity of global variable in different subprocess returns the same value, but when i modify the global variable in subprocess but not work in main process? If id() returns the actual memory address of variable, but why i can't modify the value in subprocess? (I am using Python3.6[CPython] in MacOS)

import os
from multiprocessing import Process


Global_list = []
Global_number = 0


def foo(x):
    global Global_list, Global_number
    print("Pid {}, id(Global_list)={}, id(Global_number)={}".format(os.getpid(), id(Global_list), id(Global_number)))
    Global_list.append(x)
    Global_number += x
    print("After: Pid {}, id(Global_list)={}, id(Global_number)={}\n".format(os.getpid(), id(Global_list), id(Global_number)))

if __name__ == '__main__':
    la = [1, 2, 3, 4]

    p_list = []

    for i in la:
        process = Process(target=foo, args=(i,))
        p_list.append(process)
        process.start()

    for p in p_list:
        p.join()

    print("In main process, id(Global_list)={}, id(Global_number)={}".format(id(Global_list), id(Global_number)))
    print("After all: Global_list={}, Global_number={}".format(Global_list, Global_number))

RESULT:

Pid 42061, id(Global_list)=4347140936, id(Global_number)=4305316864
After: Pid 42061, id(Global_list)=4347140936, id(Global_number)=4305316896

Pid 42062, id(Global_list)=4347140936, id(Global_number)=4305316864
After: Pid 42062, id(Global_list)=4347140936, id(Global_number)=4305316928

Pid 42063, id(Global_list)=4347140936, id(Global_number)=4305316864
After: Pid 42063, id(Global_list)=4347140936, id(Global_number)=4305316960

Pid 42064, id(Global_list)=4347140936, id(Global_number)=4305316864
After: Pid 42064, id(Global_list)=4347140936, id(Global_number)=4305316992

In main process, id(Global_list)=4347140936, id(Global_number)=4305316864
After all: Global_list=[], Global_number=0

Upvotes: 3

Views: 754

Answers (2)

Daniel Pryden
Daniel Pryden

Reputation: 60997

You appear to have a fundamental misunderstanding. Within the same process, if id() returns the same value for two different objects then that means they have the same object identity (and modifications to one will be visible to the other).

id() is only unique within one process. If you have multiple processes in use, you can (and likely will!) have id() return the same value for different objects, which may be of the same type, or may even have the same values (e.g. if you used os.fork() to create the subprocess), but do not have the same identity: changes to one will not be reflected in the other.

More generally, this is true in all modern operating systems: each process has its own independent "view" of memory (called "virtual memory"), and can use any address it likes (subject to various OS-level restrictions, e.g. sbrk or mmap). Every process in the system can have an object at address 4347140936, and they can all be different objects from each other. Many operating systems depend on this behavior -- for example, a shared library might always be loaded into memory at the same place, and functions that call into it might depend on that being the case.

That said, if you are using various shared memory or object remoting mechanisms, you can have modifications to an object in one process reflected to an object in another process. But in that case, you actually have two objects, just two "interconnected" objects -- and that means that id() will return different values, even though the objects are "the same" at a conceptual level.

Upvotes: 3

debug
debug

Reputation: 1079

>>> Global_list = []
>>> id(Global_list)
4351947464
>>> Global_list.append(1)
>>> id(Global_list)
4351947464

>>> Global_number = 0
>>> id(Global_number)
4305328480
>>> Global_number += 1
>>> id(Global_number)
4305328512  ----> different address

If you try to assign a value to the same variable name, its memory address is changed.

Upvotes: 0

Related Questions