How can I get the return value of a function passed to multiprocessing.Process?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
A function passed to multiprocessing.Process does not return a value directly to the parent process. The child runs in a separate process with separate memory, so you have to send results back explicitly through inter-process communication.
Why A Normal Return Statement Does Not Help
A Process target looks like a normal Python function, but it is not being called in the same address space as the parent.
worker returns 20, but the parent never receives it. The process simply exits.
So the real question is not "how do I access the return value" but "which IPC primitive should carry the result back."
Use A Queue For General Results
A queue is the most common answer.
This works well for one result, many results, or even structured payloads.
A queue is usually the right first choice because it scales to multiple workers and keeps the parent-child contract explicit.
Use A Pipe For One-To-One Communication
If there is exactly one child and one parent exchanging a small amount of data, Pipe is simpler.
This is lightweight, but less convenient than a queue if the design grows beyond one child and one message stream.
Use A Pool If You Really Want Return Values
If your workload is really "run a function on many inputs and collect the results," multiprocessing.Pool is a better abstraction than manual Process objects.
This is closer to ordinary function return semantics and is often what people actually want.
Handling Errors Properly
A child process can fail before sending a result. If the parent blindly waits on q.get() or recv(), it can block forever.
A safer queue pattern is to send structured output:
This makes failures visible to the parent instead of disappearing inside the child.
Do Not Forget The Main Guard
On platforms that use spawn-based startup, especially Windows, always protect process creation with:
Without that guard, the module can be re-imported during child startup and create runaway process spawning.
A Modern Alternative
If you want futures and normal-looking result retrieval, concurrent.futures.ProcessPoolExecutor is often easier to integrate:
This is not the same API as Process, but for many applications it is the better tool.
Common Pitfalls
The most common mistake is expecting a Process target's return value to come back automatically. It will not.
Another mistake is using global variables to share results. Separate processes do not share ordinary Python objects the way threads do.
Developers also block forever waiting for a queue item that the child never sent because the child crashed first.
Finally, some code uses raw Process objects when a pool or executor is the real abstraction needed. That adds boilerplate for no benefit.
Summary
- '
multiprocessing.Processdoes not give you direct return values.' - Use
QueueorPipeto send results back explicitly. - Use
PoolorProcessPoolExecutorwhen you want function-like result handling. - Send structured success and error payloads for robustness.
- Always use the
if __name__ == "__main__":guard when starting child processes.

