LoginSignup
9
7

More than 3 years have passed since last update.

EventとQueueを使ってマルチスレッドなズンドコキヨシ

Last updated at Posted at 2016-06-03

マルチスレッド動作を確認したくて、ズンドコキヨシを作ってみました。
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()
9
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7