Python 3.15+threadingfunction
threading.synchronized_iterator()
iterators across threads
A decorator for a generator function: every iterator it returns is already wrapped in serialize_iterator and safe for several threads.
Syntax
@threading.synchronized_iterator
def gen(...):
yield ...
More convenient than wrapping every call by hand: put @threading.synchronized_iterator above def squares(n) and any squares(10) can be shared between threads. The original function's name, docstring and __wrapped__ are preserved. Each iterator gets its own lock rather than one per function, so two calls of the generator do not block each other. Each item goes to exactly one thread: this is a work queue, not a broadcast.
Examples
import threading
@threading.synchronized_iterator
def squares(n):
for x in range(n):
yield x * x
print(squares.__name__) # → squares
got = []
it = squares(50)
threads = [threading.Thread(target=lambda: got.extend(it)) for _ in range(3)]
for t in threads: t.start()
for t in threads: t.join()
print(sorted(got) == [x * x for x in range(50)]) # → True
See also
Open in the full glossarydocs.python.orgReport an inaccuracy