Python学習【365日チャレンジ!】206日目のマスターU(@Udemy11)です。
最近の若者は日本語がきちんとできていないということをよく耳にしますが、若者に限らず、文章を理解する力が下がっているようです。
まず、本を読む機会が少なくなって、人とコミュニケーションを取る機会も少なくなれば、当然日本語を話す理解するという機会が減ってるわけです。
わたしたちは小さな頃からの莫大な会話数によって、言語を習得しているわけなので、使わなくなれば、能力は下がる一方です。
作家やブロガーでもない限り、文章を書く機会も少ないので、読みやすく、わかりやすい文章を書こうと思っても経験がないからかけないわけです。
文章を書くからには、しっかりと読み返して、おかしなところがないかチェックしているのですが、たまにおかしな文章になっていることもあるので、改めて気をつけようと思います。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日は、スレッドに渡す引数について学習しました。
Thread
オブジェクトを生成する際に、いくつかの引数を指定することができましたが、target
には、関数を指定しましたが、加えてname
やargs
、kwargs
を使ってコードを書きました。
今日は、その引数のdaemon
について学習します。
デーモンスレッド
デーモンというと、「デーモン小暮」しか思い浮かんでこないのですが、プログラミングの世界では、システムに常駐しているソフトのことで、なにかやらないといけないことができてきたときに処理をしてくれるらしいです。
PythonのThread
オブジェクトに用意されている引数のdaemon
の場合で考えると、スレッドをデーモン化することで、デーモン化されたスレッド意外のスレッドの処理が終了したら、プログラムを終了するので、常駐しているソフトとは少し意味合いが違うような感じがします。
ただ、ネットにはバックグラウンドで作動しているプログラムという解説もあるので、処理の終了を意識する必要がないという定義で考えて、デーモンスレッドといわれているのかもしれません。
解説していてもよくわからないので、実際にコードを書いていきましょう。
thread.py
thread.py
は、昨日のコードから少し変更しています。
import logging
import threading
import time
logging.basicConfig(
level=logging.DEBUG, format='%(threadName)s: %(message)s')
def thread1():
logging.debug('start1')
time.sleep(1)
logging.debug('end1')
def thread2():
logging.debug('start2')
time.sleep(5)
logging.debug('end2')
if __name__ == '__main__':
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t2.setDaemon(True)
t1.start()
t2.start()
print('started')
昨日のコードから変更している部分は、10行目と15行目のtime.sleep
をそれぞれ1
と5
にして、19行目、20行目でThread
の引数をtarget
だけにして、21行目にt2.setDaemon(True)
を追加しました。
threadingモジュールを確認するとわかりますが、Thread
オブジェクトの引数であるdaemon
は、デフォルトでNone
になっています。
スレッドをデーモン化するには、setDaemon
を使ってdaemon
をTrue
に指定します。
ちなみに、21行目を削除して、20行目を次のように変更しても同じようにデーモン化が可能です。
t2 = threading.Thread(target=thread2, daemon=True)
コードが書けたら実行してみましょう。
実行結果
/Users/bigmacpro/opt/anaconda3/bin/python /Users/bigmacpro/PycharmProjects/thread/thread.py
started
Thread-1: start1
Thread-2: start2
Thread-1: end1
Process finished with exit code 0
スレッドが並列処理されているので、started
が最初に出力されています。
デーモン化していなければ、Thread-1: end1
が出力された4秒後にThread-2: end2
と表示されますが、デーモン化されたスレッド以外が終了しているため、Thread-1: end1
が出力された時点でプログラムが終了します。
joinで待機
スレッドをデーモン化するということは、処理に時間がかかるスレッドを途中で投げ出す可能性があるということなので、デーモン化するスレッドは、データを取得して書き込むような処理は向いていません。
デーモン化したスレッドが終了するまでプログラムの終了を待たせるために使うのがjoin
です。
t2.join()
thread.py
のコードの最終行25行目に上記コードを追加します。
join
を使って、デーモン化したt2
オブジェクトが終了するまでプログラムの終了を待機するようになります。
/Users/bigmacpro/opt/anaconda3/bin/python /Users/bigmacpro/PycharmProjects/thread/thread.py
Thread-1: start1
Thread-2: start2
started
Thread-1: end1
Thread-2: end2
Process finished with exit code 0
今回は、前回出力されなかったThread-2: end2
が出力されます。
ちなみに、join
はデーモン化していないスレッドにも使えるので、明示的な意味からデーモン化していないt1
も同様にt1.join()
と記述するプログラマーもいるとのことです。
実践あるのみ
毎回言っているような気がしますが、大切なのは、やってみることです。
実際にコードを書いて、ちょっとづつコードを変更してみたりして、動作を確認したりするとより理解が深まります。
今回のデーモン化も基本的な使い方はわかっても、具体的にどんな場面で使うのかちょっとイメージができないので、いろいろと試しつつ実践に備えたいと思います。
それでは明日もGood Python!