I know that generators are not thread safe . When accessing two streams simultaneously, an error occurs:
ValueError: the generator is already executing
But iterators are different from generators when they are used in several threads, an exception does not occur, but there will be race conditions. See this article for a comparison of generators and iterators.
In these articles, the author uses an example when two threads access the counter at the same time, as a result of which his "self.i" state is incorrectly updated:
class Counter:
def __init__(self):
self.i = 0
def __iter__(self):
return self
def next(self):
self.i += 1
return self.i
so when the threads stop, self.i will not equal the number of times it is updated by two threads, but less.
, ? :
import threading
class Counter(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.num_seen = 0
self.lock = threading.Lock()
def run(self):
global total
for x in idata:
self.num_seen += 1
print('{0} {1}'.format(self.name, self.num_seen))
with self.lock:
total += self.num_seen
count = 10000000
idata = iter([i for i in xrange(count)])
total = 0
nthreads = 5
threads = [Counter() for n in xrange(nthreads)]
for t in threads:
t.start()
for t in threads:
t.join()
print('total ' + str(total))
, , , ?