Pythonのthreading.eventを学習します

Python学習【365日チャレンジ!】215日目のマスターU(@Udemy11)です。

そろそろ釣りにとってはベストなシーズンに入って、例年なら、どんな魚でも数が釣れるようになるのですが、今年はなかなかうまく群れを捕まえることができていません。

釣果情報を見るとやはりたくさん釣れている情報がちらほらあるにも関わらず、どうもいい感じに!?外してしまっているみたいです。

釣具屋さんのスタッフの方が釣りまくっているみたいなので、一緒に連れて行ってもらいたいのですが、なかなか話しかけることもできないので、どうしたもんですかね。

と言いつつも時間ができるとついつい釣りに行っちゃうんですよね。

それでは、今日もPython学習をはじめましょう。

昨日の復習

昨日は、queueの実践的な使い方について学習しました。

時間のかかる処理を複数のスレッドで分割して処理する作業をqueueを使って実践してみましたが、理解するには何度もコードを書く必要があると感じました。

少しむずかしい処理ですが、何度も試してみるとある程度動きも見えてきて、どのような処理をしているのかを理解することができます。

具体的な使い方に近いコードなので、昨日学習したコードを少しずつ変更してみてどのように処理されるのか試してみましょう。

今日は、イベントについて学習します。

waitとset

イベントは、一つのスレッドを先に処理して、終了してからちがうスレッドをスタートさせるような使い方ができます。

import logging
import threading
import time

logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')

def thread1(event):
    event.wait()
    logging.debug('start1')
    time.sleep(2)
    logging.debug('end1')

def thread2(event):
    event.wait()
    logging.debug('start2')
    time.sleep(2)
    logging.debug('end2')

def thread3(event):
    logging.debug('start3')
    time.sleep(2)
    logging.debug('end3')
    event.set()

if __name__ == '__main__':
    event = threading.Event()
    t1 = threading.Thread(target=thread1, args=(event, ))
    t2 = threading.Thread(target=thread2, args=(event, ))
    t3 = threading.Thread(target=thread3, args=(event, ))
    t1.start()
    t2.start()
    t3.start()

引数にeventを入れるのは、オブジェクト化したlocksemaphorequeueなどと一緒ですね。

コードはこれまでのかんたんなものと同じで、関数thread1thread2thread3を作ってeventオブジェクトを引数に入れています。

thread1thread2には、最初にevent.wait()を入れて、thread3には、最後にevent.set()を入れています。

ここまで一緒に学習してこられた方ならおわかりだと思いますが、thread3の処理が終了してから、thread1thread2の処理が始まります。

実行結果

Thread-3: start3
Thread-3: end3
Thread-2: start2
Thread-1: start1
Thread-2: end2
Thread-1: end1

最初の1行が出力されたあと、2秒後に2〜4行目が出力されて、2秒経過後に5行目と6行目が出力されてプログラムが終了します。

Thread-3つまり関数thread3が実行されて、終了したあと、Thread-1(関数thread1)とThread-2(関数thead2)が並列処理されるという感じですね。

似たよな感じ

酒井さんの講座の解説やコードをみていると、「lockなどを使っても同じことができるんじゃない?」なんて思っちゃいます。

lambdaや内包表記と同じ感じで、多分できるんだろうけど、利便性を高めたのがeventだという理解でいいのかもしれません。

ライブラリにしても、もともとあるメソッドなどを使って、より便利に使えるようにしているだけなので、回答は求める必要はありませんが、モジュールを覗いてみてthreading.event()がどのような処理をしているのか理解しておくと、のちのち役立つかもしれません。

ここまで学習してきたスレッドのコードについては、かなり似通っている感じがするので、ある意味threadingについては、かなり繰り返して学習できているかもしれません。

とはいえ、何も考えずにコードをタイプしているだけだと、記憶には定着していないので、何歩か下がりながら、記憶の定着化を目指しましょう!

それでは、明日もGood Python!