マルチスレッド動作を確認したくて、ズンドコキヨシを作ってみました。
3人の歌手にスレッド動作してもらい、1秒間隔で「ズン」か「ドコ」を歌ってもらいます。
Queueはマルチスレッド対応で、複数スレッドから格納されたデータを順番に取り出すことができます。これをマイクに見立てています。
スレッドが違っても同じオブジェクトを参照するはずなので、ZUN か DOKO かを ==
ではなく is
を使って比較しています。
#!/usr/bin/env python3
import time
from random import random
from threading import Thread, Event
from queue import Queue
ZUN = "ズン"
DOKO = "ドコ"
KIYOSHI = "キ・ヨ・シ!"
class Singer(Thread):
def __init__(self, mic):
'''準備: マイクを持って、開始と終了の指示を待つ'''
super().__init__()
self.mic = mic
self.singing = Event()
def run(self):
'''開始: 1秒毎にズンかドコを歌う'''
self.singing.set()
while self.singing.is_set():
time.sleep(1)
word = ZUN if random() < 0.5 else DOKO
self.mic.put(word)
def stop(self):
'''終了: 歌い終わる'''
if self.singing.is_set():
self.singing.clear()
self.join()
def zundoko():
# マイク
mic = Queue()
# 歌手3人に1つのマイクに向かって歌い始めてもらう
the_number_of_singer = 3
singers = [Singer(mic) for i in range(the_number_of_singer)]
for singer in singers:
singer.start()
try:
# 「ズン」が4回続いたあとに「ドコ」が聞こえたら「キ・ヨ・シ!」と叫ぶ
zun = 0
kiyoshi = False
while kiyoshi == False:
word = mic.get()
print(word)
if word is ZUN:
zun += 1
elif word is DOKO:
if zun >= 4:
kiyoshi = True
zun = 0
print(KIYOSHI)
finally:
# 歌手に歌い終ってもらう (CTRL+Cで強制終了させられたときも)
for singer in singers:
singer.stop()
if __name__ == '__main__':
zundoko()