Python学習【365日チャレンジ!】210日目のマスターU(@Udemy11)です。
テレビをつけながらブログを書いているとついついドラマに見入ってしまいます。
特に、半沢直樹は現在の水戸黄門のような勧善懲悪ドラマなので、結論がわかっているのにハラハラドキドキしながらみてしまいます。
とはいえ、ブログに本腰を入れられないので、テレビから離れて作業したほうがいいかもしれません。
それでは、今日もPython学習をはじめましょう。
記事の内容は、酒井潤さんの講座を参考にさせていただき、学習した内容を紹介しています。
Pythonをひととおり学習したい人にはピッタリの講座で、セールの際は、値段も専門書1冊の値段よりも安く受講できるので、超おすすめの講座です。
昨日の復習
昨日は、スレッドのLockについて学習しました。
スレッドは並列処理ができるものの、同じ変数の計算をしてしまうと代入に関してバグが起こる可能性がありましたが、thread.Lock
を使えば、そのバグを回避することができました。
具体的な使用シーンはまだまだイメージできないのですが。。。
今日は、Lockに関係するRLockを学習します。
withを使ってthread
thread.Lock
でオブジェクトを作って、acquire
とrelease
で他のスレッドの処理を止めることができましたが、にwith
ステートメントを使って同じような処理をさせることができます。
import logging
import threading
import time
logging.basicConfig(level=logging.DEBUG, format='%(threadName)s: %(message)s')
def thread1(d, lock):
logging.debug('start1')
with.lock:
i = d['x']
time.sleep(1)
d['x'] = i + 1
logging.debug(d)
logging.debug('end1')
def thread2(d, lock):
logging.debug('start2')
lock.acquire()
i = d['x']
d['x'] = i + 1
logging.debug(d)
lock.release()
logging.debug('end2')
if __name__ == '__main__':
d = {'x': 1}
lock = threading.Lock()
t1 = threading.Thread(target=thread1, args=(d, lock))
t2 = threading.Thread(target=thread2, args=(d, lock))
t1.start()
t2.start()
ハイライトしている部分がwith
ステートメントを使ったlock
の場合、自動的に開いて閉じるので、lock.release
は必要ありません。
実行結果
Thread-1: start1
Thread-2: start2
Thread-1: {'x': 2}
Thread-1: end1
Thread-2: {'x': 3}
Thread-2: end2
2行目までが出力されたあと、1秒後に残りの行が出力されます。
thread1
とthread2
はコードが違いますが、同じ意味合いになります。
with内with
次に、with
ステートメントの中にさらにwith
ステートメントを使ったlock
を入れるとどうなるでしょう?
def thread1(d, lock):
logging.debug('start1')
with.lock:
i = d['x']
time.sleep(1)
d['x'] = i + 1
logging.debug(d)
with lock:
d['x'] = i + 1
logging.debug('end1')
with
ステートメントを入れ子にすると、16行目まで処理がされたあと、lock.release
されていない状態でwith lock
が来るので、ずっとlock.release
を待った状態になってしまいます。
実行結果
Thread-1: start1
Thread-2: start2
Thread-1: {'x': 2}
プログラムが終了しない状態になるので、この状態を回避するためにRLock
を使います。
Rlock
先程のコードからlock = threading.Lock()
をlock = threading.RLock()
に変更するだけです。
lock = threading.RLock()
RLock
を使うことで、release
されていない状態のコード内でlock
を使うことができ、内部のlock
をrelease
したあと、外部のlock
をrelease
してくれます。
わからないこともある
わからないことはわかるまでやってみることが大切だといっていますが、考えてもわからないときは一旦離れてみることも重要です。
離れてみてちがうことを学習したあとに、復習してみると、意外と簡単に理解できることがあります。
他の知識を吸収することでそれまでは理解できなかったことがわかるようになっているわけです。
すぐにわからないと諦めるのではなく、しっかりと実践して最終的に理解できなかったことは、一旦忘れてしまってみてください。
ふとした時に道がひらけたように理解できることもありますから。
それでは明日もGood Python!