4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

「threadingを使用して開始したスレッド」を強制終了する

Last updated at Posted at 2023-07-02

結論

threading.Threadを継承したカスタムスレッドクラスを用意し、強制終了する関数を用意させておきます。これによって強制終了が可能になります。ただし、Threadingにはそもそも直接強制終了させる手段がないという点を知った上での自己責任で実装したほうが良さそうです。

サンプルコード

.py
import threading

import ctypes
import time

# カスタムスレッドクラス
class twe(threading.Thread):
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        threading.Thread.__init__(self, group=group, target=target, name=name)
        self.args = args
        self.kwargs = kwargs
        return
    
    def run(self):
        self._target(*self.args, **self.kwargs)

    def get_id(self):
        if hasattr(self, '_thread_id'):
            return self._thread_id
        for id, thread in threading._active.items():
            if thread is self:
                return id
    
    # 強制終了させる関数
    def raise_exception(self):
        thread_id = self.get_id()
        resu = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), ctypes.py_object(SystemExit))
        if resu > 1:
            ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread_id), 0)
            print('Failure in raising exception')

# 開始するスレッドで実行する関数
def sample_func(a, b, c, hoge1 = None, hoge2 = None, hoge3 = None):
    try:
        while True:
            print((a, b, c, hoge1, hoge2, hoge3))
            time.sleep(1)
    finally:
          print('ended')

def main():
    # 開始するスレッドを定義
    # targetに実行する関数
    # args, kwargsには関数に渡す引数
    x = twe(name = 'Thread A', target=sample_func, args=(1, 2, 3), kwargs={'hoge1': 'hogehoge1', 'hoge2': 'hogehoge2', 'hoge3': 'hogehoge3'})
    # スレッド開始
    x.start()
    # 10秒間、開始したスレッドが処理し続ける
    time.sleep(10)
    # raise_exceptionを呼び出すことでスレッドが終了
    x.raise_exception()
    # 既に終了しているので処理を待機しないはず
    x.join()

if __name__ == '__main__':
    main() 
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
(1, 2, 3, 'hogehoge1', 'hogehoge2', 'hogehoge3')
ended

注意事項

threadingはそもそも直接強制終了する手段を提供していないようです。だからこそ、カスタムクラスを用意して実装させているわけです。おそらく、threadingを使用するときは安全にスレッドを終了させてほしいという意味もあると思います。このことを知った上で自己責任で実装したほうが良さそうです。

以上です。

参考

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?