Python: is it safe to get a value from the same list iterator in multiple threads?

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))

, , , ?

+4
1

, , , Python, . , CPython, , CPython. : , . , . , , .

, . , @9000, deque, "... ".

0

All Articles