PEP 255: Simple Generators
Tim Peters
tim.one at home.com
Mon Jun 25 04:06:54 EDT 2001
[Greg Copeland]
> So what happens when you have two threads calling a generator. I
> guess they are distinct...
That depends on whether you created a distinct generator for each thread, or
shared a common one. If Threads A and B both do
for x in g():
yadda(x)
it may or may not be thread-safe, depending on how g was implemented; if it
sticks to using local vrbls, it probably will be; if it mucks around
mutating globals without benefit of synchronization constructs, probably
not.
If thread A alone instead does:
iter = g()
and iter is visible to both A and B, and then they both do
while 1:
x = iter.next()
yadda(x)
then they're sharing a single iterator object, and an exception is the most
likely outcome: while an instance of a generator-function is running, it's
a detected error to try to invoke it again before it yields (hmm! I should
add that to the PEP). If the threads manage to avoid that, they'll see
disjoint subsequences of g()'s full sequence (which may well be a *feature*
if synchronized properly: "thread safe" is relative to what an app is
trying to accomplish, it's not an absolute thing).
If you stick to the for-loop spelling, it's easy to write thread-safe
generators. For example, the tree-traversal generators in the PEP can be
used simultaneously by multiple for-loops in multiple threads without
problems. Despite persistent rumors to the contrary <wink>, generators
*are* functions, and each invocation gets its own local variables and local
instruction pointer and local stack space etc.
More information about the Python-list
mailing list