Short Summary

As of CY2023, the technique described in this answer is quite out of date. These days, use concurrent.futures.ProcessPoolExecutor() instead of multiprocessing, below...

This answer describes the benefits and shortcomings of using concurrent.futures.ProcessPoolExecutor(). FYI, multiple python processes are sometimes used instead of threading to get the most benefit from concurrency. That said, python threading works pretty well as long as there is sufficient CPU activity to avoid the GIL (activity such as sending / receiving network traffic).

Original Answer

My main problem is that I really don't know how to implement multiprocessing.queue correctly, you cannot really instantiate the object for each process since they will be separate queues, how do you make sure that all processes relate to a shared queue (or in this case, queues)

This is a simple example of a reader and writer sharing a single queue... The writer sends a bunch of integers to the reader; when the writer runs out of numbers, it sends 'DONE', which lets the reader know to break out of the read loop.

You can spawn as many reader processes as you like...

from multiprocessing import Process, Queue
import time
import sys


def reader_proc(queue):
    """Read from the queue; this spawns as a separate Process"""
    while True:
        msg = queue.get()  # Read from the queue and do nothing
        if msg == "DONE":
            break


def writer(count, num_of_reader_procs, queue):
    """Write integers into the queue.  A reader_proc() will read them from the queue"""
    for ii in range(0, count):
        queue.put(ii)  # Put 'count' numbers into queue

    ### Tell all readers to stop...
    for ii in range(0, num_of_reader_procs):
        queue.put("DONE")


def start_reader_procs(qq, num_of_reader_procs):
    """Start the reader processes and return all in a list to the caller"""
    all_reader_procs = list()
    for ii in range(0, num_of_reader_procs):
        ### reader_p() reads from qq as a separate process...
        ###    you can spawn as many reader_p() as you like
        ###    however, there is usually a point of diminishing returns
        reader_p = Process(target=reader_proc, args=((qq),))
        reader_p.daemon = True
        reader_p.start()  # Launch reader_p() as another proc

        all_reader_procs.append(reader_p)

    return all_reader_procs


if __name__ == "__main__":
    num_of_reader_procs = 2
    qq = Queue()  # writer() writes to qq from _this_ process
    for count in [10**4, 10**5, 10**6]:
        assert 0 < num_of_reader_procs < 4
        all_reader_procs = start_reader_procs(qq, num_of_reader_procs)

        writer(count, len(all_reader_procs), qq)  # Queue stuff to all reader_p()
        print("All reader processes are pulling numbers from the queue...")

        _start = time.time()
        for idx, a_reader_proc in enumerate(all_reader_procs):
            print("    Waiting for reader_p.join() index %s" % idx)
            a_reader_proc.join()  # Wait for a_reader_proc() to finish

            print("        reader_p() idx:%s is done" % idx)

        print(
            "Sending {0} integers through Queue() took {1} seconds".format(
                count, (time.time() - _start)
            )
        )
        print("")
Answer from Mike Pennington on Stack Overflow
🌐
Python
docs.python.org › 3 › library › multiprocessing.html
multiprocessing — Process-based parallelism
Note that one can also create a shared queue by using a manager object – see Managers. ... multiprocessing uses the usual queue.Empty and queue.Full exceptions to signal a timeout.
Top answer
1 of 7
192

Short Summary

As of CY2023, the technique described in this answer is quite out of date. These days, use concurrent.futures.ProcessPoolExecutor() instead of multiprocessing, below...

This answer describes the benefits and shortcomings of using concurrent.futures.ProcessPoolExecutor(). FYI, multiple python processes are sometimes used instead of threading to get the most benefit from concurrency. That said, python threading works pretty well as long as there is sufficient CPU activity to avoid the GIL (activity such as sending / receiving network traffic).

Original Answer

My main problem is that I really don't know how to implement multiprocessing.queue correctly, you cannot really instantiate the object for each process since they will be separate queues, how do you make sure that all processes relate to a shared queue (or in this case, queues)

This is a simple example of a reader and writer sharing a single queue... The writer sends a bunch of integers to the reader; when the writer runs out of numbers, it sends 'DONE', which lets the reader know to break out of the read loop.

You can spawn as many reader processes as you like...

from multiprocessing import Process, Queue
import time
import sys


def reader_proc(queue):
    """Read from the queue; this spawns as a separate Process"""
    while True:
        msg = queue.get()  # Read from the queue and do nothing
        if msg == "DONE":
            break


def writer(count, num_of_reader_procs, queue):
    """Write integers into the queue.  A reader_proc() will read them from the queue"""
    for ii in range(0, count):
        queue.put(ii)  # Put 'count' numbers into queue

    ### Tell all readers to stop...
    for ii in range(0, num_of_reader_procs):
        queue.put("DONE")


def start_reader_procs(qq, num_of_reader_procs):
    """Start the reader processes and return all in a list to the caller"""
    all_reader_procs = list()
    for ii in range(0, num_of_reader_procs):
        ### reader_p() reads from qq as a separate process...
        ###    you can spawn as many reader_p() as you like
        ###    however, there is usually a point of diminishing returns
        reader_p = Process(target=reader_proc, args=((qq),))
        reader_p.daemon = True
        reader_p.start()  # Launch reader_p() as another proc

        all_reader_procs.append(reader_p)

    return all_reader_procs


if __name__ == "__main__":
    num_of_reader_procs = 2
    qq = Queue()  # writer() writes to qq from _this_ process
    for count in [10**4, 10**5, 10**6]:
        assert 0 < num_of_reader_procs < 4
        all_reader_procs = start_reader_procs(qq, num_of_reader_procs)

        writer(count, len(all_reader_procs), qq)  # Queue stuff to all reader_p()
        print("All reader processes are pulling numbers from the queue...")

        _start = time.time()
        for idx, a_reader_proc in enumerate(all_reader_procs):
            print("    Waiting for reader_p.join() index %s" % idx)
            a_reader_proc.join()  # Wait for a_reader_proc() to finish

            print("        reader_p() idx:%s is done" % idx)

        print(
            "Sending {0} integers through Queue() took {1} seconds".format(
                count, (time.time() - _start)
            )
        )
        print("")
2 of 7
36

Here's a dead simple usage of multiprocessing.Queue and multiprocessing.Process that allows callers to send an "event" plus arguments to a separate process that dispatches the event to a "do_" method on the process. (Python 3.4+)

import multiprocessing as mp
import collections

Msg = collections.namedtuple('Msg', ['event', 'args'])

class BaseProcess(mp.Process):
    """A process backed by an internal queue for simple one-way message passing.
    """
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.queue = mp.Queue()

    def send(self, event, *args):
        """Puts the event and args as a `Msg` on the queue
        """
        msg = Msg(event, args)
        self.queue.put(msg)

    def dispatch(self, msg):
        event, args = msg

        handler = getattr(self, "do_%s" % event, None)
        if not handler:
            raise NotImplementedError("Process has no handler for [%s]" % event)

        handler(*args)

    def run(self):
        while True:
            msg = self.queue.get()
            self.dispatch(msg)

Usage:

class MyProcess(BaseProcess):
    def do_helloworld(self, arg1, arg2):
        print(arg1, arg2)

if __name__ == "__main__":
    process = MyProcess()
    process.start()
    process.send('helloworld', 'hello', 'world')

The send happens in the parent process, the do_* happens in the child process.

I left out any exception handling that would obviously interrupt the run loop and exit the child process. You can also customize it by overriding run to control blocking or whatever else.

This is really only useful in situations where you have a single worker process, but I think it's a relevant answer to this question to demonstrate a common scenario with a little more object-orientation.

Discussions

Help understanding how to add queue to multiprocessing.Pool
Can you elaborate which part of the code above you do not understand? The code you've posted basically starts a pool with 3 processes. Each process does what is defined in worker_main. The arguments for multiprocessing.Pool(...) are described here . First one is the number of processes, second is the function each process calls, third are the arguments for the function as a tuple. More on reddit.com
🌐 r/learnpython
9
4
October 17, 2016
Version of multiprocessing.Queue that works with unrelated processes?
I’m looking for an implementation of a cross-process queue, to pass data between two parts of my app. The only one I can find in the stdlib is multiprocessing.Queue, which requires the two processes be managed by multiprocessing (which isn’t the case for me). More on discuss.python.org
🌐 discuss.python.org
19
0
June 11, 2023
Issues with python's multiprocessing queue and large objects

First, yes I wrote this blog post. My question is, has anyone else encountered this problem? If so how did you manage to work around it?

More on reddit.com
🌐 r/Python
6
10
January 28, 2011
Filling a queue and managing multiprocessing in python - Stack Overflow
I'm having this problem in python: I have a queue of URLs that I need to check from time to time if the queue is filled up, I need to process each item in the queue Each item in the queue must be More on stackoverflow.com
🌐 stackoverflow.com
🌐
Samuelstevens
samuelstevens.me › writing › python-multiprocessing
Multiprocessing Queue Example in Python
Now we can run time python queue_demo.py and see that it takes less than 30 seconds (3 seconds * 5 elements produced * 2 producers). It’s not perfect (should be exactly 15 seconds), but it’s definitely faster than in a single process. Here’s the final program, licensed under GNU AGPLv3. If you have any improvements/suggestions, I can be reached at samuel.robert.stevens@gmail.com · import time from multiprocessing import Process, Queue def produce(q: "Queue[int]", length: int) -> None: for _ in range(length): q.put(3) q.put(-1) # stop-value def consume(q: "Queue[int]") -> None: while Tru
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-multiprocessing-queue-vs-multiprocessing-manager-queue
Python multiprocessing.Queue vs ...
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.
🌐
Medium
medium.com › @surve.aasim › process-synchronization-using-multiprocessing-queue-4a2702cc6f5e
Process Synchronization using multiprocessing.Queue | by Aasim | Medium
August 17, 2023 - The multiprocessing.Queue is a robust communication tool provided by Python's multiprocessing module, enabling secure and synchronized data exchange among multiple processes.
🌐
Reddit
reddit.com › r/learnpython › help understanding how to add queue to multiprocessing.pool
r/learnpython on Reddit: Help understanding how to add queue to multiprocessing.Pool
October 17, 2016 -

See the code from my previous thread

I have been reading up on multiprocessing queue but I do not understand how all the arguments work. The code I have already I have only just about bumbled to understand.

I read this code

import multiprocessing
import os
import time

the_queue = multiprocessing.Queue()


def worker_main(queue):
    print os.getpid(),"working"
    while True:
        item = queue.get(True)
        print os.getpid(), "got", item
        time.sleep(1) # simulate a "long" operation

the_pool = multiprocessing.Pool(3, worker_main,(the_queue,))
#                            don't forget the coma here  ^

for i in range(5):
    the_queue.put("hello")
    the_queue.put("world")


time.sleep(10)

from this SO thread. It is the simplest example I have come across so far.

I still am unsure how I would add it into the code I had in my other thread.

Could anyone give me some pointers.

What confuses me is how to cram in all the arguments in the correct places.

Thanks.

Find elsewhere
🌐
Mindee
mindee.com › blog of mindee › ai ocr › why are multiprocessing queues slow when sharing large objects in python?
Slow multiprocessing queues python - Mindee
March 2, 2023 - Multiprocessing queues in Python allow multiple processes to safely exchange objects with each other. However, these queues can become slow when large objects are being shared between processes.
🌐
Super Fast Python
superfastpython.com › multiprocessing-queue-in-python
Multiprocessing Queue in Python – SuperFastPython
May 27, 2022 - Python provides a process-safe queue in the multiprocessing.Queue class.
🌐
Python.org
discuss.python.org › python help
Version of multiprocessing.Queue that works with unrelated processes? - Python Help - Discussions on Python.org
June 11, 2023 - I’m looking for an implementation of a cross-process queue, to pass data between two parts of my app. The only one I can find in the stdlib is multiprocessing.Queue, which requires the two processes be managed by multipr…
🌐
DigitalOcean
digitalocean.com › community › tutorials › python-multiprocessing-example
Python Multiprocessing Example: Process, Pool & Queue | DigitalOcean
March 31, 2026 - Use multiprocessing.Queue whenever you need to pass data between separate processes. Same-process usage mirrors the standard library queue API: put enqueues, get dequeues. # Tested on Python 3.11 from multiprocessing import Queue def main(): colors = ["red", "green", "blue", "black"] cnt = 1 queue = Queue() print("pushing items to queue:") for color in colors: print("item no: ", cnt, " ", color) queue.put(color) cnt += 1 print("\npopping items from queue:") cnt = 0 while not queue.empty(): print("item no: ", cnt, " ", queue.get()) cnt += 1 if __name__ == "__main__": main()
🌐
Reddit
reddit.com › r/python › issues with python's multiprocessing queue and large objects
r/Python on Reddit: Issues with python's multiprocessing queue and large objects
January 28, 2011 - Using queue.get(block=False) will almost never work right. Think of the case where you are using a slow generator to feed work items to the workers. If you use block=False they will exit before they even got the first work item. The only thing I do differently is send work items as a tuple of a boolean and the work item.. like: ... The official Python community for Reddit!
🌐
Real Python
realpython.com › ref › stdlib › multiprocessing
multiprocessing | Python Standard Library – Real Python
Supports local concurrency and remote concurrency with multiprocessing.managers and explicit setups · Offers process pools for simple parallel task management · Provides shared data structures such as queues and pipes · Creating a process: Language: Python ·
🌐
Medium
suryabhusal11.medium.com › multiprocessing-ipc-with-multiple-queues-52ea434196a6
Multiprocessing IPC with multiple Queues | by surya bhusal | Medium
November 27, 2021 - If timeout is a positive number, it blocks at most timeout seconds and raises the queue.Empty exception if no item was available within that time. Otherwise (block is False), return an item if one is immediately available, else raise the queue.Empty exception (timeout is ignored in that case).
🌐
GitHub
github.com › python › cpython › blob › main › Lib › multiprocessing › queues.py
cpython/Lib/multiprocessing/queues.py at main · python/cpython
# Module implementing queues · # # multiprocessing/queues.py · # # Copyright (c) 2006-2008, R Oudkerk · # Licensed to PSF under a Contributor Agreement. # · __all__ = ['Queue', 'SimpleQueue', 'JoinableQueue'] · import sys · import os · import threading ·
Author   python
🌐
GeeksforGeeks
geeksforgeeks.org › python › multiprocessing-python-set-1
Multiprocessing in Python | Set 1 (Introduction) - GeeksforGeeks
July 23, 2025 - The main python script has a different process ID and multiprocessing module spawns new processes with different process IDs as we create Process objects p1 and p2. In above program, we use os.getpid() function to get ID of process running the current target function.
🌐
GitHub
gist.github.com › 3358585
Python Multiprocessing Queues and Pipes · GitHub
Python Multiprocessing Queues and Pipes. GitHub Gist: instantly share code, notes, and snippets.
🌐
Medium
medium.com › @AlexanderObregon › understanding-pythons-multiprocessing-module-744dba8d4be4
Understanding Python’s Multiprocessing Module | Medium
August 10, 2024 - Inter-process communication (IPC) is crucial for enabling processes to exchange data and synchronize their actions. The multiprocessing module provides several mechanisms for IPC, including Queue, Pipe, Value, and Array.
Top answer
1 of 3
65

You could use the blocking capabilities of queue to spawn multiple process at startup (using multiprocessing.Pool) and letting them sleep until some data are available on the queue to process. If your not familiar with that, you could try to "play" with that simple program:

import multiprocessing
import os
import time

the_queue = multiprocessing.Queue()


def worker_main(queue):
    print os.getpid(),"working"
    while True:
        item = queue.get(True)
        print os.getpid(), "got", item
        time.sleep(1) # simulate a "long" operation

the_pool = multiprocessing.Pool(3, worker_main,(the_queue,))
#                           don't forget the comma here  ^

for i in range(5):
    the_queue.put("hello")
    the_queue.put("world")


time.sleep(10)

Tested with Python 2.7.3 on Linux

This will spawn 3 processes (in addition of the parent process). Each child executes the worker_main function. It is a simple loop getting a new item from the queue on each iteration. Workers will block if nothing is ready to process.

At startup all 3 process will sleep until the queue is fed with some data. When a data is available one of the waiting workers get that item and starts to process it. After that, it tries to get an other item from the queue, waiting again if nothing is available...

2 of 3
13

Added some code (submitting "None" to the queue) to nicely shut down the worker threads, and added code to close and join the_queue and the_pool:

import multiprocessing
import os
import time

NUM_PROCESSES = 20
NUM_QUEUE_ITEMS = 20  # so really 40, because hello and world are processed separately


def worker_main(queue):
    print(os.getpid(),"working")
    while True:
        item = queue.get(block=True) #block=True means make a blocking call to wait for items in queue
        if item is None:
            break

        print(os.getpid(), "got", item)
        time.sleep(1) # simulate a "long" operation


def main():
    the_queue = multiprocessing.Queue()
    the_pool = multiprocessing.Pool(NUM_PROCESSES, worker_main,(the_queue,))
            
    for i in range(NUM_QUEUE_ITEMS):
        the_queue.put("hello")
        the_queue.put("world")
    
    for i in range(NUM_PROCESSES):
        the_queue.put(None)

    # prevent adding anything more to the queue and wait for queue to empty
    the_queue.close()
    the_queue.join_thread()

    # prevent adding anything more to the process pool and wait for all processes to finish
    the_pool.close()
    the_pool.join()

if __name__ == '__main__':
    main()
Top answer
1 of 1
22

Why is q.put() not blocking??

mutiprocessing.Queue creates a pipe which blocks if the pipe is already full. Of course writing more than the pipe capacity will cause the write call to block until the reading end has cleared enough data. Ok, so if the pipe blocks when its capacity is reached, why is q.put() not also blocking once the pipe is full? Even the first call to q.put() in the example should fill up the pipe, and everything should block there, no?

No, it does not block, because the multiprocessing.Queue implementation decouples the .put() method from writes to the pipe. The .put() method enqueues the data passed to it in an internal buffer, and there is a separate thread which is charged with reading from this buffer and writing to the pipe. This thread will block when the pipe is full, but it will not prevent .put() from enqueuing more data into the internal buffer.

The implementation of .put() saves the data to self._buffer and note how it kicks off a thread if there is not one already running:

def put(self, obj, block=True, timeout=None):
    assert not self._closed
    if not self._sem.acquire(block, timeout):
        raise Full

    with self._notempty:
        if self._thread is None:
            self._start_thread()
        self._buffer.append(obj)
        self._notempty.notify()

The ._feed() method is what reads from self._buffer and feeds the data to the pipe. And ._start_thread() is what sets up a thread that runs ._feed().

How can I limit queue size?

If you want to limit how much data can be written into a queue, I don't see a way to do it by specifying a number of bytes but you can limit the number of items that are stored in the internal buffer at any one time by passing a number to multiprocessing.Queue:

q = multiprocessing.Queue(2)

When I use the parameter above, and use your code, q.put() will enqueue two items, and will block on the third attempt.

Are Python piped communications inter-operable with other non-Python processes?

It depends. The facilities provided by the multiprocessing module are not easily interoperable with other languages. I expect it would be possible to make multiprocessing interoperate with other languages, but achieving this goal would be a major enterprise. The module is written with the expectation that the processes involved are running Python code.

If you look at more general methods, then the answer is yes. You could use a socket as a communication pipe between two different processes. For instance, a JavaScript process that reads from a named socket:

var net = require("net");
var fs = require("fs");

sockPath = "/tmp/test.sock"
try {
    fs.unlinkSync(sockPath);
}
catch (ex) {
    // Don't care if the path does not exist, but rethrow if we get
    // another error.
    if (ex.code !== "ENOENT") {
        throw ex;
    }
}

var server = net.createServer(function(stream) {
  stream.on("data", function(c) {
    console.log("received:", c.toString());
  });

  stream.on("end", function() {
    server.close();
  });
});

server.listen(sockPath);

And a Python process that writes to it:

import socket
import time

sockfile = "/tmp/test.sock"

conn = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
conn.connect(sockfile)

count = 0
while True:
    count += 1
    conn.sendall(bytes(str(count), "utf-8"))
    time.sleep(1)

If you want to try the above, you need to start the JavaScript side first so that the Python side has something to write to. This is a proof-of-concept. A complete solution would need more polish.

In order to pass complex structures from Python to other languages, you'll have to find a way to serialize your data in a format that can be read on both sides. Pickles are unfortunately Python-specific. I generally pick JSON whenever I need to serialize between languages, or use an ad-hoc format if JSON won't do it.

🌐
Python.org
discuss.python.org › python help
When would you use Python's queue or multiprocess.queue over the OS's APIs for communicating between processes? - Python Help - Discussions on Python.org
October 4, 2023 - Is there an advantage to using Python’s queues or multiprocess.queues over PyWin32’s CreateFile, Windows Named Pipes, or python-systemd or dbus-python’s ability to do inter-process communication? Do you primarily use the…