Basic

A queue feeds workers

A queue is how many workers share one stream of work. Producers put items in, workers take them out, and a sentinel tells a worker to stop.

What you will see

soon

About 2 min of reading

Try It

Check what a queue hands out.

1

Order kept.

import queue q = queue.Queue() q.put("a") q.put("b") print(q.get())

Before you run it, say out loud what it will print. Then open the answer.

What it prints
a
2

Total drained.

import queue q = queue.Queue() for n in range(3): q.put(n) total = 0 while not q.empty(): total = total + q.get() print(total)

Before you run it, say out loud what it will print. Then open the answer.

What it prints
3
3

Sentinel stops.

import queue q = queue.Queue() q.put("job") q.put(None) item = q.get() while item is not None: item = q.get() print("stopped")

Before you run it, say out loud what it will print. Then open the answer.

What it prints
stopped
4

Priority first.

import queue q = queue.PriorityQueue() q.put((3, "late")) q.put((1, "soon")) print(q.get()[1])

Before you run it, say out loud what it will print. Then open the answer.

What it prints
soon

Put it in order

Before you write anything, put these lines back in the right order. Click a line to move it up one step. This support step is easier than writing code from scratch, and it is here to make the last example stick.

Data Flow

Producers put items, workers take items, each worker reports one item done, and a sentinel or a count ends the batch.
1 producers put items
↓
2 workers take items
↓
3 each reports done
↓
4 a sentinel ends it
Line by line

Read the first example one line at a time. A line that prints shows what appears on screen; the rest set things up quietly.

import queue sets nothing on screen
q = queue.Queue() sets nothing on screen
q.put("a") sets nothing on screen
q.put("b") sets nothing on screen
print(q.get()) a
Why this works
The queue is the contract

Workers do not know about each other. They agree on one queue, which is what makes the count of workers a free dial.

Stop needs a signal

An empty queue means more work may come. Only a sentinel or a counted end says the stream is over, so pick one and use it everywhere.

Examples

Put and take

import queue

q = queue.Queue()
q.put("a")
q.put("b")
print(q.get())
print(q.get())

get blocks when the queue is empty, so a worker waits for work instead of spinning.

One worker

import queue

q = queue.Queue()
for n in range(3):
    q.put(n)

total = 0
while not q.empty():
    total = total + q.get()
print(total)

A single worker is the serial case. The queue is still the shape, so adding workers is a small change.

Two workers

import queue

q = queue.Queue()
for n in range(4):
    q.put(n)

def worker():
    while not q.empty():
        q.get()

worker()
worker()
print(q.qsize())

Both workers drain the same queue, so the work is split between them and nothing is left.

A sentinel to stop

import queue

q = queue.Queue()
q.put("job")
q.put(None)

item = q.get()
while item is not None:
    item = q.get()
print("stopped")

A worker cannot tell an empty queue from a finished one. A sentinel item says which is which.

Task done

import queue

q = queue.Queue()
q.put("job")
item = q.get()
q.task_done()
q.join()
print(item)

task_done reports one item finished and join waits for all of them, which is how a batch ends.

A priority queue

import queue

q = queue.PriorityQueue()
q.put((3, "late"))
q.put((1, "soon"))
print(q.get()[1])

A priority queue takes the order off the workers. The item carries its own rank instead.

Words this lesson uses

Each one is defined here on this site. Open the entry for the full definition and the other words it points at.

← A lock keeps one inside
Previous Lesson
A lock keeps one inside
Next Lesson
Threads and the GIL
Threads and the GIL →