Python学習【365日チャレンジ!】211日目のマスターU(@Udemy11)です。
台風が過ぎ去ったので、最近タチウオの釣果が好調だというポイントに行ってきました。
ポイントに到着すると、電気ウキがネオンのように水面に連なっていてびっくり!!ほんと釣りブームが来てますね。
とりあえずなんとか空いている場所を確保してスタートしたのですが、まったくもって無反応。。。
少し粘ったのですが、一向に反応がないので早めに引き上げてきました。
一度、釣れすぎて困るってくらい釣りたいものです。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日は、スレッドのRLockについて学習しました。
with
ステートメントを使ってlock
したスレッドの中で、入れ子にしたlock
を扱えるようにするのがRLock
でした。
通常、lock
してrequire
したスレッドは、release
しないと入れ子のlock
したスレッドはスタートしませんが、RLock
を使うことで、入れ子のロックしたスレッドを処理をスタートさせることができました。
詳しくは昨日の記事をごらんください。
今日は、スレッドのセマフォを学習します。
semaphoreとは
semaphoreは、手信号、信号装置という意味がありますが、Pythonにおいて、並列処理を行っても問題の無いスレッドの数を指定して並行処理ができ瑠要にするものです。
lockと同じように排他制御ができますが、lockが1つのスレッドに対して、semaphoreは複数のスレッドの排他制御を行うことができます。
排他制御は、Excelなどにたとえると、共有フォルダに置いたファイルを2人の人が同時に開こうとすると、後からアクセスした人は読み込み専用になるようなものですね。
一方で、Googleスプレッドシートのように、複数の人が同時に編集することが可能なプログラムもあります。
Googleスプレッドシートがどのようにして同時編集を可能にしているのかわかりませんが、通常、編集しているものを他の人が編集できちゃうと困っちゃいますよね。
semaphoreの使い方
semaphoreの使い方は、lock
をsemaphore
に変更するだけで使えますが、排他制御をおこなうスレッドの数が引数になり、1
以上の整数を引数にとります。
import logging
import threading
import time
logging.basicConfig(
level=logging.DEBUG, format='%(threadName)s: %(message)s')
def thread1(semaphore):
logging.debug('start1')
time.sleep(1)
logging.debug('finish1')
def thread2(semaphore):
logging.debug('start2')
time.sleep(1)
logging.debug('finish2')
def thread3(semaphore):
logging.debug('start3')
time.sleep(1)
logging.debug('finish3')
if __name__ == '__main__':
semaphore = threading.Semaphore(2)
t1 = threading.Thread(target=thread1, args=(semaphore, ))
t2 = threading.Thread(target=thread2, args=(semaphore, ))
t3 = threading.Thread(target=thread3, args=(semaphore, ))
t1.start()
t2.start()
t3.start()
9行目、14行目、19行目でスレッドの引数にsemaphore
を代入していますが、代入するsemaphore
は25行目で定義しています。
26行目から28行目のThread
オブジェクトの作成の際にも、args
にsemaphore
を指定しています。
このコードを実行すると、thread1
とthread2
が実行されて、1秒後に処理が終了した後thread3
が実行される形になります。
thread-1: start1
thread-2: start2 #1秒後に次の3行が出力される
thread-1: finish1
thread-2: finish2
thread-3: start3 #1秒後に次の行が出力される
thread-3: finish3
実際にコードを書いて実行してみてほしいのですが、thread1
とthread2
が並列処理されたあとロックがリリースされ、最後にthread3
が実行されます。
並列処理をしてもかまわないスレッドと排他制御が必要なスレッドに分けて実行するような場面で使いますが、実践で使わないとなかなかイメージが難しい気がします。
コードを書く
コードを書くというよりタイプするといった方が正確ですが、同じコードがあるとついついコピーペーストしてしまいますが、コードになれないうちは、できるだけタイプした方がいいと思います。
同じコードをタイプするのとコピペするのでは、脳への刷り込み回数が全く違ってきます。
タイプすることで、何度も脳にインプットされるので、復習する時などもコードを覚えていたりしますが、コピペしていると思い出せなかったりします。
もちろんタイピングのスピードも速くなるので、コードを覚えられていないときは、面倒でもタイプするようにしましょう。
それでは明日もGood Python!