サイコロのランダムな抽選に基づいてそれぞれが 4 回実行される 3 つのスレッドの同期を制御するために、リーダー/ライター ロック メカニズムを実装しようとしています。たとえば、スレッド i の場合、random.randint(1, 6) が呼び出され、出力が偶数の場合はスレッド i が読み取られ、奇数の場合はスレッド i が書き込みになります。ここで、リーダー/ライター ロックの一般的な実装を見つけましたが、3 つのスレッドに対してこれら 4 つの操作を実行することに成功しませんでした。元のコードの一部と、最後に追加したものを次に示します。
import threading
import time, random
class RWLock:
def __init__(self):
self.rwlock = 0
self.writers_waiting = 0
self.monitor = threading.Lock()
self.readers_ok = threading.Condition(self.monitor)
self.writers_ok = threading.Condition(self.monitor)
def acquire_read(self):
self.monitor.acquire()
while self.rwlock < 0 or self.writers_waiting:
self.readers_ok.wait()
self.rwlock += 1
self.monitor.release()
def acquire_write(self):
self.monitor.acquire()
while self.rwlock != 0:
self.writers_waiting += 1
self.writers_ok.wait()
self.writers_waiting -= 1
self.rwlock = -1
self.monitor.release()
def release(self):
self.monitor.acquire()
if self.rwlock < 0:
self.rwlock = 0
else:
self.rwlock -= 1
wake_writers = self.writers_waiting and self.rwlock == 0
wake_readers = self.writers_waiting == 0
self.monitor.release()
if wake_writers:
self.writers_ok.acquire()
self.writers_ok.notify()
self.writers_ok.release()
elif wake_readers:
self.readers_ok.acquire()
self.readers_ok.notifyAll()
self.readers_ok.release()
rwl = RWLock()
class Reader(threading.Thread):
def run(self):
print "Thread " + str(threading.active_count()) + " is now ready for reading shard location\n"
rwl.acquire_read()
time.sleep(5)
print "Thread " + str(threading.active_count()) + " now has finished reading shard location\n"
rwl.release()
time.sleep(0.2)
self._is_running = False
class Writer(threading.Thread):
def run(self):
print "Thread " + str(threading.active_count()) + " is now ready to write to shard location\n"
rwl.acquire_write()
time.sleep(5)
print "Thread " + str(threading.active_count()) + " now has finished writing to shard location\n"
rwl.release()
time.sleep(0.2)
self._is_running = False
alpha = list("ABC")
d = {i: 4 for i in alpha}
def execute(thread):
global d
diceDraw = random.randint(1, 6)
if diceDraw % 2 == 0:
thread = Reader()
thread.start()
time.sleep(1)
else:
thread = Writer()
thread.start()
time.sleep(1)
while sum(d.values()) > 0:
for i in d.keys():
if i:
execute(i)
d[i] -= 1
なにか提案を?