pythonのスレッド活用というと、こんなコードがすぐに思い浮かびます。
# エンターされるまでは数字を更新して、 # エンターされたら終了する(つもり) import time import threading flag = True def th(): i = 0 while flag: print("\r{}:".format(i), end="") i += 1 time.sleep(3) th = threading.Thread(target=th) th.start() input() flag = False
これは期待と違う動作になります(エンター押してから最大3秒後にならないと終了しない)。sleep中に条件の判定をしてくれる訳はないからです。
どうやって意図通りの動作にするかというと、threading.Eventを使うと楽です。
threading --- スレッドベースの並列処理 — Python 3.7.4 ドキュメント
import threading def th(): i = 0 while True: print("\r{}:".format(i), end="") i += 1 if event.wait(timeout=3): # ここにイベントが発生したときの処理を書く break event = threading.Event() th = threading.Thread(target=th) th.start() input() event.set()
Event.waitにtimeoutを指定するとsleep代わりに使えます。要諦としては、
- Eventの内部に持つフラグをclearメソッドでFalseに、setメソッドでTrueに切り替えられる。デフォルトはFalse
- 内部フラグがTrueならwaitメソッドは即座に返る。Falseの場合はTrueになるまで(他スレッドがsetするまで)永遠に待つのがデフォルトの動作だが、timeoutを指定するとその期間待ってから返る
- waitメソッドはtimeoutしたとき(だけ)はFalseを返す。それ以外はTrue
というあたりで、活用すると面白いコードが書けます。