異なるスレッドからアクセスされるシングルトンがあります。このシングルトンは、ジェネレーターでデータを提供しています。ジェネレーターは、データにアクセスするスレッドによって完全に消費される必要があります。データにアクセスする各スレッドは、新しいジェネレーターを消費する必要があります。これは私のコードです:
from datetime import datetime
import threading
import time
class MySingletonCls:
def get_data(self, repeat):
self.nr = 0
for x in xrange(repeat):
time.sleep(0.001)
self.nr += 1
yield x
_my_singleton = None
def MySingleton():
global _my_singleton
if _my_singleton == None:
_my_singleton = MySingletonCls()
return _my_singleton
def test_singleton():
def worker():
singleton = MySingleton()
cnt = 0
for x in singleton.get_data(100):
cnt += 1
print singleton.nr, cnt
threads = []
num_worker_threads = 5
for i in range(num_worker_threads):
t = threading.Thread(target=worker)
threads.append(t)
t.start()
for t in threads:
t.join()
test_singleton()
各ワーカーが 100 エントリを受け取ると予想しますが、実際はそうです。しかし、シングルトンでカウンターにアクセスすると、非常に奇妙な数値が得られます。これは私のプログラムの出力です:
457 100
468 100
470 100
471 100
475 100
ここで何が起こっているのですか?スレッドごとにシングルトン ジェネレーターを生成しているエントリの数は? シングルトン カウンターがこの奇妙な値を示しているのはなぜですか? これをスレッドセーフにするにはどうすればよいですか?