Python でスレッドを強制的に終了させたい: イベントを設定して、スレッドがそれをチェックして終了するまで待ちたくありません。のような簡単な解決策を探していkill -9
ます。プライベートメソッドなどで操作するような汚いハックなしでそれを行うことは可能ですか?
3 に答える
コードの実行速度が約 10 倍遅くなることを気にしない場合は、Thread2
以下に実装されたクラスを使用できます。次の例は、新しいstop
メソッドを呼び出すと、次のバイトコード命令でスレッドを強制終了する方法を示しています。
import threading
import sys
class StopThread(StopIteration): pass
threading.SystemExit = SystemExit, StopThread
class Thread2(threading.Thread):
def stop(self):
self.__stop = True
def _bootstrap(self):
if threading._trace_hook is not None:
raise ValueError('Cannot run thread with tracing!')
self.__stop = False
sys.settrace(self.__trace)
super()._bootstrap()
def __trace(self, frame, event, arg):
if self.__stop:
raise StopThread()
return self.__trace
class Thread3(threading.Thread):
def _bootstrap(self, stop_thread=False):
def stop():
nonlocal stop_thread
stop_thread = True
self.stop = stop
def tracer(*_):
if stop_thread:
raise StopThread()
return tracer
sys.settrace(tracer)
super()._bootstrap()
################################################################################
import time
def main():
test = Thread2(target=printer)
test.start()
time.sleep(1)
test.stop()
test.join()
def printer():
while True:
print(time.time() % 1)
time.sleep(0.1)
if __name__ == '__main__':
main()
このThread3
クラスは、クラスよりも約 33% 高速にコードを実行するようですThread2
。
スレッドは終了すると終了します。
スレッドにできるだけ早く終了するように通知できますが、これはスレッドで実行されているコードのコラボレーションを前提としており、それが発生した場合の上限は保証されません。
古典的な方法は、のような変数を使用し、exit_immediately = False
スレッドのメインルーチンに定期的に変数をチェックさせ、値が。の場合は終了させることですTrue
。スレッドを終了させるには、すべてのスレッドを設定exit_immediately = True
して呼び出します。.join()
明らかに、これはスレッドが定期的にチェックインできる場合にのみ機能します。
一部のスレッドに何が起こるかを気にせずに、プログラムを最後に終了できるようにすることだけが必要な場合は、daemon
スレッドが必要です。
ドキュメントから:
生きている非デーモン スレッドがなくなると、Python プログラム全体が終了します。
使用プログラムの例:
import threading
import time
def test():
while True:
print "hey"
time.sleep(1)
t = threading.Thread(target=test)
t.daemon = True # <-- set to False and the program will not terminate
t.start()
time.sleep(10)
豆知識:スレッドは.Netではスレッドdaemon
と呼ばれます。background