プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/02/18

[Python] マルチスレッド

event_note2022/02/18 2:12

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 の代わりに acquirerelease を使ってもいいです。

** 出力結果 **

start
already running
already running
2022-02-14 14:29:16.802901 running
...
stopping
stopped
not running
not running

既にスレッド起動中の場合は一度停止してから再起動

上記の print('already running') のところで self.stop() をコールすればよいです。