produceとcomsumeが同じではないので、結果的に、速度が遅い方に引っ張られることになる。
import time from threading import Thread, Semaphore, Lock SIZE = 5 BUFFER = ["" for i in range(SIZE)] producer_idx: int = 0 mutex = Lock() empty = Semaphore(SIZE) full = Semaphore(0) class Producer(Thread): def __init__(self, name: str, maximum_items: int = 5): super().__init__() self.counter = 0 self.name = name self.maximum_items = maximum_items def next_index(self, index: int) -> int: return (index + 1) % SIZE def run(self) -> None: global producer_idx while self.counter < self.maximum_items: empty.acquire() mutex.acquire() self.counter += 1 BUFFER[producer_idx] = f"{self.name}-{self.counter}" print(f"{self.name} produced: " f"'{BUFFER[producer_idx]}' into slot {producer_idx}") producer_idx = self.next_index(producer_idx) mutex.release() full.release() time.sleep(1) class Consumer(Thread): def __init__(self, name: str, maximum_items: int = 10): super().__init__() self.name = name self.idx = 0 self.counter = 0 self.maximum_items = maximum_items def next_index(self) -> int: return (self.idx + 1) % SIZE def run(self) -> None: while self.counter < self.maximum_items: full.acquire() mutex.acquire() item = BUFFER[self.idx] print(f"{self.name} consumed item: " f"'{item}' from slot {self.idx}") self.idx = self.next_index() self.counter += 1 mutex.release() empty.release() time.sleep(2) if __name__ == "__main__": threads = [ Producer("SpongeBob"), Producer("Patrick"), Consumer("Squidward") ] for thread in threads: thread.start() for thread in threads: thread.join()
$ python3 producer_comsumer.py
SpongeBob produced: ‘SpongeBob-1’ into slot 0
Patrick produced: ‘Patrick-1’ into slot 1
Squidward consumed item: ‘SpongeBob-1’ from slot 0
SpongeBob produced: ‘SpongeBob-2’ into slot 2
Patrick produced: ‘Patrick-2’ into slot 3
Squidward consumed item: ‘Patrick-1’ from slot 1
Patrick produced: ‘Patrick-3’ into slot 4
SpongeBob produced: ‘SpongeBob-3’ into slot 0
Patrick produced: ‘Patrick-4’ into slot 1
Squidward consumed item: ‘SpongeBob-2’ from slot 2
SpongeBob produced: ‘SpongeBob-4’ into slot 2
Squidward consumed item: ‘Patrick-2’ from slot 3
Patrick produced: ‘Patrick-5’ into slot 3
Squidward consumed item: ‘Patrick-3’ from slot 4
SpongeBob produced: ‘SpongeBob-5’ into slot 4
Squidward consumed item: ‘SpongeBob-3’ from slot 0