Python学習【365日チャレンジ!】212日目のマスターU(@Udemy11)です。
エスプレッソを作ってミルクを泡立てて、久しぶりにスターバックスのマグカップを使ってラテをを入れてみたのですが、かなりボリュームがありました。
通常のコーヒーカップって200mlあるかないかくらいだと思うのですが、スタバのマグは400mlはありますからね。
単純計算で体重が0.4kg太っちゃうわけです。
案の定、体重は増えてたので、ラテを飲むときは、通常のコーヒーカップを使うようにします。
それでは、今日もPython学習をはじめましょう。
昨日の復習
昨日は、semaphoreについて学習しました。
通常ならロックしたスレッドの処理は一つ一つ順番に処理をしますが、semaphoreを使えば、ロックした2つ以上のスレッドを並列処理させることができました。
並列処理をさせたあと、その結果を使って別のスレッドに値を渡すという感じで使うことができました。
詳細については、昨日の記事をごらんください。
今日は、キュー(queue)を学習します。
Queue
「Queだけでいいんじゃないの?」と思ってしまうのは私だけでしょうか?
公式ドキュメントを見ると、そんなQueue
には、3種類のQueue
オブジェクトが用意されているようです。
- queue.Queue(FIFOキュー)
- queue.Lifoqueue(LIFOキュー)
- queue.PriorityQueue(優先順位付きキュー)
今日は、この中のqueue.Queue
を学習しますが、これらのQueue
はリストのように値を入れて取り出すことができます。
値を入れた順番のまま取り出せるのがqueue.Queue(FIFOキュー)
で、「First in First out」といわれ、最初に入れたものを最初に出します。
次のqueue.Lifoqueue(LIFOキュー)
は、「Last in First out」といわれ、最後に入れたものを最初に出します。
最後のqueue.PriorityQueue(優先順位付きキュー)
は、優先順位をつけて入れて、その優先順位順に取り出します。
queue.Queue
ファースト・イン・ファースト・アウトのqueue.Queue
は、値を入れて取り出す処理ができるので、2つのスレッドで値をやり取りすることができます。
import logging
import queue
import threading
import time
logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')
def thread1(queue):
logging.debug('start1')
queue.put('Yes')
time.sleep(2)
queue.put('No')
logging.debug('end1')
def thread2(queue):
logging.debug('start2')
logging.debug(queue.get())
logging.debug(queue.get())
logging.debug('end2')
if __name__ == '__main__':
queue = queue.Queue()
t1 = threading.Thread(target=thread1, args=(queue, ))
t2 = threading.Thread(target=thread2, args=(queue, ))
t1.start()
t2.start()
lock
やsemaphore
と同じように、22行目でqueue
オブジェクトを作成しています。
23行目、24行目のargs
の引数にはqueue
を指定して、8行目、15行目のスレッド関数の引数にもqueue
を指定しています。
あとは、thread1
でput
を使ってYes
とNo
を入れて、thread2
のget
でqueue
に入れた順番に出力しています。
time.sleep
は、動作がわかりやすいように入れていますが、実際に使うときは必要ありません。
このコードの実行結果は次のようになります。
Thread-1: start1
Thread-2: start2
Thread-2: Yes #この行の出力後、2秒後に次の行が出力される
Thread-1: end1
Thread-2: No
Thread-2: end2
thread1
とthread2
は並列処理がされるので、9・10行目、16・17行目が処理されて、実行結果の3行目まで出力されたあと、11行目のtime.sleep
によって、2秒待ちます。
この間、thread2
の18行目queue.get()
は、queue
に2つ目の値がput
されるのを待機した状態になっています。
2秒後にthread1
の12行目でNo
がqueue
に入れられると同時に18行目のget
でNo
が出力されています。
lock
されたスレッドの終了を待っている次のスレッドのような感じですね。
似たような感じ
lock
にしてもsemaphore
にしてもqueue
にしても処理的には似たような感じがします。
この微妙な違いを理解して使い分けられるようになるには、やはり数をこなすしかないと思うので、地道にコードを書いていくしかないのが現実です。
かのアインシュタインもこのように言ってますよね。
何かを学ぶのに、自分自身で経験する以上に良い方法はない
経験を積み重ねていきましょう!
それでは明日もGood Python!