Manager proxy objects are unable to propagate changes made to (unmanaged) mutable objects inside a container. So in other words, if you have a manager.list() object, any changes to the managed list itself are propagated to all the other processes. But if you have a normal Python list inside that list, any changes to the inner list are not propagated, because the manager has no way of detecting the change.

In order to propagate the changes, you have to use manager.list() objects for the nested lists too (requires Python 3.6 or newer), or you need to modify the manager.list() object directly (see the note on manager.list in Python 3.5 or older).

For example, consider the following code and its output:

import multiprocessing
import time

def f(ns, ls, di):
    ns.x += 1
    ns.y[0] += 1
    ns_z = ns.z
    ns_z[0] += 1
    ns.z = ns_z

    ls[0] += 1
    ls[1][0] += 1 # unmanaged, not assigned back
    ls_2 = ls[2]  # unmanaged...
    ls_2[0] += 1
    ls[2] = ls_2  # ... but assigned back
    ls[3][0] += 1 # managed, direct manipulation

    di[0] += 1
    di[1][0] += 1 # unmanaged, not assigned back
    di_2 = di[2]  # unmanaged...
    di_2[0] += 1
    di[2] = di_2  # ... but assigned back
    di[3][0] += 1 # managed, direct manipulation

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    ns = manager.Namespace()
    ns.x = 1
    ns.y = [1]
    ns.z = [1]
    ls = manager.list([1, [1], [1], manager.list([1])])
    di = manager.dict({0: 1, 1: [1], 2: [1], 3: manager.list([1])})

    print('before', ns, ls, ls[2], di, di[2], sep='\n')
    p = multiprocessing.Process(target=f, args=(ns, ls, di))
    p.start()
    p.join()
    print('after', ns, ls, ls[2], di, di[2], sep='\n')

Output:

before
Namespace(x=1, y=[1], z=[1])
[1, [1], [1], <ListProxy object, typeid 'list' at 0x10b8c4630>]
[1]
{0: 1, 1: [1], 2: [1], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}
[1]
after
Namespace(x=2, y=[1], z=[2])
[2, [1], [2], <ListProxy object, typeid 'list' at 0x10b8c4630>]
[2]
{0: 2, 1: [1], 2: [2], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}
[2]

As you can see, when a new value is assigned directly to the managed container, it changes; when it is assigned to a mutable container within the managed container, it doesn't change; but if the mutable container is then reassigned to the managed container, it changes again. Using a nested managed container also works, detecting changes directly without having to assign back to the parent container.

Answer from senderle on Stack Overflow
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ multiprocessing.html
multiprocessing โ€” Process-based parallelism
For more flexibility in using shared ... manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies....
Top answer
1 of 2
99

Manager proxy objects are unable to propagate changes made to (unmanaged) mutable objects inside a container. So in other words, if you have a manager.list() object, any changes to the managed list itself are propagated to all the other processes. But if you have a normal Python list inside that list, any changes to the inner list are not propagated, because the manager has no way of detecting the change.

In order to propagate the changes, you have to use manager.list() objects for the nested lists too (requires Python 3.6 or newer), or you need to modify the manager.list() object directly (see the note on manager.list in Python 3.5 or older).

For example, consider the following code and its output:

import multiprocessing
import time

def f(ns, ls, di):
    ns.x += 1
    ns.y[0] += 1
    ns_z = ns.z
    ns_z[0] += 1
    ns.z = ns_z

    ls[0] += 1
    ls[1][0] += 1 # unmanaged, not assigned back
    ls_2 = ls[2]  # unmanaged...
    ls_2[0] += 1
    ls[2] = ls_2  # ... but assigned back
    ls[3][0] += 1 # managed, direct manipulation

    di[0] += 1
    di[1][0] += 1 # unmanaged, not assigned back
    di_2 = di[2]  # unmanaged...
    di_2[0] += 1
    di[2] = di_2  # ... but assigned back
    di[3][0] += 1 # managed, direct manipulation

if __name__ == '__main__':
    manager = multiprocessing.Manager()
    ns = manager.Namespace()
    ns.x = 1
    ns.y = [1]
    ns.z = [1]
    ls = manager.list([1, [1], [1], manager.list([1])])
    di = manager.dict({0: 1, 1: [1], 2: [1], 3: manager.list([1])})

    print('before', ns, ls, ls[2], di, di[2], sep='\n')
    p = multiprocessing.Process(target=f, args=(ns, ls, di))
    p.start()
    p.join()
    print('after', ns, ls, ls[2], di, di[2], sep='\n')

Output:

before
Namespace(x=1, y=[1], z=[1])
[1, [1], [1], <ListProxy object, typeid 'list' at 0x10b8c4630>]
[1]
{0: 1, 1: [1], 2: [1], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}
[1]
after
Namespace(x=2, y=[1], z=[2])
[2, [1], [2], <ListProxy object, typeid 'list' at 0x10b8c4630>]
[2]
{0: 2, 1: [1], 2: [2], 3: <ListProxy object, typeid 'list' at 0x10b8c4978>}
[2]

As you can see, when a new value is assigned directly to the managed container, it changes; when it is assigned to a mutable container within the managed container, it doesn't change; but if the mutable container is then reassigned to the managed container, it changes again. Using a nested managed container also works, detecting changes directly without having to assign back to the parent container.

2 of 2
29

ns is a NamespaceProxy instance. These objects have special __getattr__, __setattr__, and __delattr__ methods that allow values to be shared across processes. In order to take advantage of this mechanism when changing a value, you must trigger __setattr__.

ns.x.append(10)

causes ns.__getattr__ to be called to retrieve ns.x, but it does not cause ns.__setattr__ to be called.

To fix this, you must use ns.x = ....

def f(ns):   
    tmp = ns.x     # retrieve the shared value
    tmp.append(10)
    ns.x = tmp     # set the shared value
๐ŸŒ
Zpz
zpz.github.io โ€บ blog โ€บ python-mp-manager-1
Reading and Hacking Python's multiprocessing.managers: Part 1
May 15, 2024 - This is one sufficient condition for Python to loop through it. See this example: The utilities for inter-process synchronization (lock, event, semaphore, etc) and data sharing (queues) are supported by threading utilities in the server; they gain inter-process capabilities thanks to the multiprocessing manager mechanism.
๐ŸŒ
Super Fast Python
superfastpython.com โ€บ multiprocessing-manager
What is a Multiprocessing Manager โ€“ SuperFastPython
August 29, 2022 - Multiprocessing Manager provides a way of creating centralized Python objects that can be shared safely among processes.
๐ŸŒ
GitHub
github.com โ€บ python โ€บ cpython โ€บ blob โ€บ main โ€บ Lib โ€บ multiprocessing โ€บ managers.py
cpython/Lib/multiprocessing/managers.py at main ยท python/cpython
# Module providing manager classes for dealing ยท # with shared objects ยท # # multiprocessing/managers.py ยท # # Copyright (c) 2006-2008, R Oudkerk ยท # Licensed to PSF under a Contributor Agreement. # ยท __all__ = [ 'BaseManager', 'SyncManager', 'BaseProxy', 'Token' ] ยท
Author: python
๐ŸŒ
DEV Community
dev.to โ€บ zenulabidin โ€บ python-multiprocessing-learning-pools-managers-and-challenges-at-lightspeed-1e29
Python Multiprocessing: Learning Pools, Managers and Challenges at Lightspeed - DEV Community
December 6, 2019 - Today I'm going to take a jab at the multiprocessing Python module. Specifically I'm going cover: ... Now lets begin. In a nutshell, manager holds inter-process synchronization primitives.
Find elsewhere
๐ŸŒ
Super Fast Python
superfastpython.com โ€บ multiprocessing-manager-example
Multiprocessing Manager Example in Python โ€“ SuperFastPython
August 30, 2022 - The multiprocessing.Manager provides the full multiprocessing API, allowing Python objects and concurrency primitives to be shared among processes.
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ python-multiprocessing-queue-vs-multiprocessing-manager-queue
Python multiprocessing.Queue vs multiprocessing.manager().Queue() - GeeksforGeeks
January 30, 2026 - The multiprocessing.manager().Queue() is a class provided by the multiprocessing module in Python that allows for the creation of a queue that can be used by multiple processes to pass messages to each other.
๐ŸŒ
Beautiful Soup
tedboy.github.io โ€บ python_stdlib โ€บ generated โ€บ generated โ€บ multiprocessing.Manager.html
multiprocessing.Manager() โ€” Python Standard Library
multiprocessing.Manager() View page source ยท multiprocessing.Manager()[source]ยถ ยท Returns a manager associated with a running server process ยท
๐ŸŒ
Medium
medium.com โ€บ @surve.aasim โ€บ process-synchronization-using-multiprocessing-manager-de5098b253d0
Process Synchronization using multiprocessing.Manager | by Aasim | Medium
August 17, 2023 - The multiprocessing.Manager serves as a valuable utility within Python's multiprocessing module, designed to simplify the sharing of data and objects among multiple processes.
๐ŸŒ
Python Module of the Week
pymotw.com โ€บ 2 โ€บ multiprocessing โ€บ communication.html
Communication Between Processes - Python Module of the Week
The Pool class can be used to manage a fixed number of workers for simple cases where the work to be done can be broken up and distributed between workers independently. The return values from the jobs are collected and returned as a list. The pool arguments include the number of processes and a function to run when starting the task process (invoked once per child). import multiprocessing def do_calculation(data): return data * 2 def start_process(): print 'Starting', multiprocessing.current_process().name if __name__ == '__main__': inputs = list(range(10)) print 'Input :', inputs builtin_out
๐ŸŒ
Stack Overflow
stackoverflow.com โ€บ questions โ€บ tagged โ€บ multiprocessing-manager
Newest 'multiprocessing-manager' Questions - Stack Overflow
I have been researching but couldn't solve this one with the lack of documentation on multiprocessing.Manager().dict(). I'm trying to download tickers information from yahoo finance using ... ... I'm trying to process a pydantic object with the multiprocessing toolbox in Python.
๐ŸŒ
Python
docs.python.org โ€บ 3.4 โ€บ library โ€บ multiprocessing.html
17.2. multiprocessing โ€” Process-based parallelism โ€” Python 3.4.10 documentation
June 16, 2019 - For more flexibility in using shared ... from shared memory. ... A manager object returned by Manager() controls a server process which holds Python objects and allows other processes to manipulate them using proxies....
๐ŸŒ
Super Fast Python
superfastpython.com โ€บ multiprocessing-manager-custom-class
Multiprocessing Manager With a Custom Class โ€“ SuperFastPython
August 31, 2022 - A manager in the multiprocessing module provides a way to create Python objects that can be shared easily between processes.
๐ŸŒ
GitHub
gist.github.com โ€บ g-clef โ€บ ec7a4bcb94223821331df5aaf3cfc7bd
Using Python's Multiprocessing Managers to share a queue between hosts ยท GitHub
To share a queue between hosts with Python, you can use a "SyncManager". There'll be one machine that's the manager/owner of the queue, and then multiple other machines can connect to that queue to pull jobs. You can also share multiprocessing Events (for example a "shutdown" Event to tell all the workers on the queue that they should stop).
๐ŸŒ
YouTube
youtube.com โ€บ how to fix your computer
PYTHON : How to use a multiprocessing.Manager()? - YouTube
PYTHON : How to use a multiprocessing.Manager()? [ Gift : Animated Search Engine : https://www.hows.tech/p/recommended.html ] PYTHON : How to use a multipro...
Published: December 6, 2021
Views: 449