1. Qiita
  2. 投稿
  3. Python

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

  • 3
    いいね
  • 1
    コメント

マルチスレッド動作を確認したくて、ズンドコキヨシを作ってみました。
3人の歌手にスレッド動作してもらい、1秒間隔で「ズン」か「ドコ」を歌ってもらいます。
Queueはマルチスレッド対応で、複数スレッドから格納されたデータを順番に取り出すことができます。これをマイクに見立てています。
スレッドが違っても同じオブジェクトを参照するはずなので、ZUN か DOKO かを == ではなく is を使って比較しています。

# -*- coding:utf-8 -*-

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(Singer, self).__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()
Comments Loading...