# Created on savesnippets.com ยท https://savesnippets.com/xXHtwVvAIFUgwX import queue import threading import time SENTINEL = object() q: queue.Queue = queue.Queue(maxsize=100) def producer(n: int): for i in range(n): q.put(f"job-{i}") q.put(SENTINEL) # one sentinel per consumer def consumer(name: str): while True: item = q.get() if item is SENTINEL: q.task_done() print(f"{name} done") return print(f"{name} -> {item}") time.sleep(0.05) q.task_done() NUM_CONSUMERS = 3 threads = [threading.Thread(target=consumer, args=(f"c{i}",)) for i in range(NUM_CONSUMERS)] for t in threads: t.start() producer(20) for _ in range(NUM_CONSUMERS - 1): q.put(SENTINEL) for t in threads: t.join()