python でのスレッドの作成、開始、終了の方法です。いつもどうだったっけ?となるので、出来るだけシンプルなコードでメモしておきます。
環境
- Python 3.8.10
スレッドの起動と停止
import time
from threading import Thread
from datetime import datetime
class Sample:
def __init__(self):
self.__is_running = False
def start(self):
print('start')
self.__is_running = True
self.__thread = Thread(target=self.__run)
self.__thread.start()
def stop(self):
print('stopping')
self.__is_running = False
self.__thread.join()
print('stopped')
def __run(self):
while self.__is_running:
print(f'{datetime.now()} running')
time.sleep(1)
if __name__ == '__main__':
sample = Sample()
sample.start()
time.sleep(10)
sample.stop()
排他処理
上記をベースに、スレッドを複数開始しないように排他をかけてみます。
import time
from threading import Thread, Lock
from datetime import datetime
class Sample:
def __init__(self):
self.__lock = Lock()
self.__is_running = False
def start(self):
if self.__is_running:
print('already running')
else:
with self.__lock:
print('start')
self.__is_running = True
self.__thread = Thread(target=self.__run)
self.__thread.start()
def stop(self):
if not self.__is_running:
print('not running')
else:
with self.__lock:
print('stopping')
self.__is_running = False
self.__thread.join()
print('stopped')
def __run(self):
while self.__is_running:
print(f'{datetime.now()} running')
time.sleep(1)
if __name__ == '__main__':
sample = Sample()
sample.start()
sample.start()
sample.start()
time.sleep(10)
sample.stop()
sample.stop()
sample.stop()
with
の代わりに acquire
と release
を使ってもいいです。
** 出力結果 **
start
already running
already running
2022-02-14 14:29:16.802901 running
...
stopping
stopped
not running
not running
既にスレッド起動中の場合は一度停止してから再起動
上記の print('already running')
のところで self.stop()
をコールすればよいです。