How to Share a Dict and List Between Processes with multiprocessing Manager in Python

This code demonstrates how to share a dictionary and a list between multiple processes using multiprocessing.Manager, enabling safe concurrent updates.

Medium Python 3.9+ Aug 9, 2026 Concurrency & performance 14 views 0 copies

Python code

29 lines
Python 3.9+
import multiprocessing as mp


def worker(shared_dict, shared_list, name):
    shared_dict[name] = name.upper()
    shared_list.append(name)
    print(f"{name} added to shared structures")


def main():
    with mp.Manager() as manager:
        shared_dict = manager.dict()
        shared_list = manager.list()

        processes = []
        for name in ["alpha", "beta", "gamma"]:
            p = mp.Process(target=worker, args=(shared_dict, shared_list, name))
            processes.append(p)
            p.start()

        for p in processes:
            p.join()

        print("Final shared dict:", dict(shared_dict))
        print("Final shared list:", list(shared_list))


if __name__ == "__main__":
    main()

Output

stdout
alpha added to shared structures
beta added to shared structures
gamma added to shared structures
Final shared dict: {'alpha': 'ALPHA', 'beta': 'BETA', 'gamma': 'GAMMA'}
Final shared list: ['alpha', 'beta', 'gamma']

How it works

multiprocessing.Manager creates server processes that host shared objects, allowing multiple processes to read and write them safely. The dict() and list() methods return proxy objects that handle synchronization internally. Each worker function updates the shared structures and prints confirmation, so the final state reflects all updates. Using with mp.Manager() ensures the manager server is properly shut down after all processes complete.

Common mistakes

  • Forgetting to join processes before reading the final shared state, causing incomplete data.
  • Assuming native dict/list operations are atomic with Manager proxies; they are synchronized but not always atomic for compound operations.
  • Passing the Manager object itself instead of the individual proxy objects to worker processes.

Variations

  1. Use `manager.Namespace()` to create a shared object with attributes that can be updated.
  2. Use `multiprocessing.Array` and `multiprocessing.Value` for simpler shared primitives without Manager overhead.

Real-world use cases

  • Aggregating results from parallel workers into a shared dictionary for a MapReduce-style job.
  • Maintaining a shared configuration store that multiple processes update during a distributed simulation.
  • Collecting logs or metrics from multiple child processes into a shared list for centralized processing.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Concurrency & performance

Related tutorials and quizzes for this topic.