回答:
Pythonや任意の言語でスレッドを突然強制終了することは、一般的に悪いパターンです。次の場合を考えてください。
(独自のスレッドを管理している場合)余裕がある場合にこれを処理する優れた方法は、exit_requestフラグを設定し、各スレッドが定期的にチェックして、終了する時間かどうかを確認することです。
例えば:
import threading
class StoppableThread(threading.Thread):
"""Thread class with a stop() method. The thread itself has to check
regularly for the stopped() condition."""
def __init__(self, *args, **kwargs):
super(StoppableThread, self).__init__(*args, **kwargs)
self._stop_event = threading.Event()
def stop(self):
self._stop_event.set()
def stopped(self):
return self._stop_event.is_set()
このコードでstop()
は、スレッドを終了させたいときにスレッドを呼び出し、を使用してスレッドが適切に終了するまで待機する必要がありますjoin()
。スレッドは定期的に停止フラグをチェックする必要があります。
ただし、スレッドを強制終了する必要がある場合もあります。例としては、長い呼び出しでビジーな外部ライブラリをラップしていて、それを中断したい場合があります。
次のコードでは、Pythonスレッドで(いくつかの制限付きで)例外を発生させることができます。
def _async_raise(tid, exctype):
'''Raises an exception in the threads with id tid'''
if not inspect.isclass(exctype):
raise TypeError("Only types can be raised (not instances)")
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid),
ctypes.py_object(exctype))
if res == 0:
raise ValueError("invalid thread id")
elif res != 1:
# "if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"
ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
raise SystemError("PyThreadState_SetAsyncExc failed")
class ThreadWithExc(threading.Thread):
'''A thread class that supports raising exception in the thread from
another thread.
'''
def _get_my_tid(self):
"""determines this (self's) thread id
CAREFUL : this function is executed in the context of the caller
thread, to get the identity of the thread represented by this
instance.
"""
if not self.isAlive():
raise threading.ThreadError("the thread is not active")
# do we have it cached?
if hasattr(self, "_thread_id"):
return self._thread_id
# no, look for it in the _active dict
for tid, tobj in threading._active.items():
if tobj is self:
self._thread_id = tid
return tid
# TODO: in python 2.6, there's a simpler way to do : self.ident
raise AssertionError("could not determine the thread's id")
def raiseExc(self, exctype):
"""Raises the given exception type in the context of this thread.
If the thread is busy in a system call (time.sleep(),
socket.accept(), ...), the exception is simply ignored.
If you are sure that your exception should terminate the thread,
one way to ensure that it works is:
t = ThreadWithExc( ... )
...
t.raiseExc( SomeException )
while t.isAlive():
time.sleep( 0.1 )
t.raiseExc( SomeException )
If the exception is to be caught by the thread, you need a way to
check that your thread has caught it.
CAREFUL : this function is executed in the context of the
caller thread, to raise an excpetion in the context of the
thread represented by this instance.
"""
_async_raise( self._get_my_tid(), exctype )
(に基づいてKillableスレッド Tomer Filibaによって。の戻り値についての引用PyThreadState_SetAsyncExc
が表示されますが、からのものであるとのPythonの古いバージョン。)
ドキュメントに記載されているように、これは魔法の弾丸ではありません。スレッドがPythonインタープリターの外部でビジー状態の場合、割り込みをキャッチしないからです。
このコードの適切な使用パターンは、スレッドが特定の例外をキャッチしてクリーンアップを実行することです。そうすれば、タスクを中断しても適切なクリーンアップを行うことができます。
SO_REUSEADDR
を回避するためにソケットオプションを使用できAddress already in use
ます。
None
代わりに渡す必要があり、それを呼び出して、tidを直接ではなく任意のctypes関数に渡さなければなりませんでした。0
res != 1
ctypes.c_long(tid)
それを行う公式のAPIはありません。
スレッドを強制終了するには、プラットフォームAPI(pthread_kill、TerminateThreadなど)を使用する必要があります。このようなAPIには、たとえばpythonwinやctypesを介してアクセスできます。
これは本質的に安全ではないことに注意してください。削除されたスレッドが削除された時点でGILがある場合、(収集されたスタックフレームのローカル変数から)収集不能なガベージが発生し、デッドロックが発生する可能性があります。
multiprocessing.Process
缶p.terminate()
スレッドを強制終了したいが、フラグ/ロック/シグナル/セマフォ/イベント/その他は使用したくない場合は、スレッドを完全なプロセスに昇格させます。少数のスレッドのみを使用するコードの場合、オーバーヘッドはそれほど悪くありません。
たとえば、これはブロッキングI / Oを実行するヘルパー「スレッド」を簡単に終了するのに便利です
変換は簡単です:関連するコードでは、すべて置き換えるthreading.Thread
とmultiprocessing.Process
、すべてのqueue.Queue
とのmultiprocessing.Queue
との必要な呼び出しを追加p.terminate()
その子を殺すために望んでいるあなたの親プロセスにp
のPythonドキュメントをmultiprocessing
参照してください。
multiprocessing
いいですが、引数は新しいプロセスにピクルされます。したがって、引数の1つが(のようにlogging.log
)ピッキングできないものである場合、を使用することはお勧めできませんmultiprocessing
。
multiprocessing
引数はWindowsの新しいプロセスにピクルされますが、Linuxはforkを使用してそれらをコピーします(Python 3.7、他のバージョンは不明)。つまり、Linuxでは機能しますが、Windowsではピクルエラーが発生するコードになります。
プログラム全体を終了しようとしている場合は、スレッドを「デーモン」として設定できます。Thread.daemonを参照
他の人が述べたように、標準は停止フラグを設定することです。軽量なもの(スレッドのサブクラス化なし、グローバル変数なし)の場合、ラムダコールバックはオプションです。(の括弧に注意してくださいif stop()
。)
import threading
import time
def do_work(id, stop):
print("I am thread", id)
while True:
print("I am thread {} doing something".format(id))
if stop():
print(" Exiting loop.")
break
print("Thread {}, signing off".format(id))
def main():
stop_threads = False
workers = []
for id in range(0,3):
tmp = threading.Thread(target=do_work, args=(id, lambda: stop_threads))
workers.append(tmp)
tmp.start()
time.sleep(3)
print('main: done sleeping; time to stop the threads.')
stop_threads = True
for worker in workers:
worker.join()
print('Finis.')
if __name__ == '__main__':
main()
常にフラッシュする()関数で置き換えるprint()
と、シェル出力の精度が向上する場合があります。pr()
sys.stdout.flush()
(Windows / Eclipse / Python3.3でのみテスト済み)
pr()
機能とは?
これはthread2-killableスレッド(Pythonレシピ)に基づいています
PyThreadState_SetasyncExc()を呼び出す必要があります。これはctypesを通じてのみ利用できます。
これはPython 2.7.3でのみテストされていますが、他の最近の2.xリリースでも動作する可能性があります。
import ctypes
def terminate_thread(thread):
"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance
"""
if not thread.isAlive():
return
exc = ctypes.py_object(SystemExit)
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(
ctypes.c_long(thread.ident), exc)
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None)
raise SystemError("PyThreadState_SetAsyncExc failed")
KeyboardInterrupt
にクリーンアップする機会を与えています。その後もハングしている場合SystemExit
は、適切であるか、ターミナルからプロセスを強制終了します。
pthread_cleanup_push()/_pop()
、正しく実装するのに多くの作業が必要になり、インタープリターの速度が著しく低下します。
スレッドに協力せずにスレッドを強制的に強制終了してはなりません。
スレッドを強制終了すると、設定がtry / finallyにブロックされるという保証がなくなるため、ロックをロックしたままにしたり、ファイルを開いたりすることができます。
スレッドを強制的に強制終了するのが良い考えであると主張できるのは、プログラムを高速に強制終了することですが、単一のスレッドを強制することはありません。
Pythonでは、スレッドを直接強制終了することはできません。
スレッド(!)が本当に必要ない場合、スレッドパッケージを使用する代わりに、マルチプロセッシングパッケージを使用する ことができます。ここで、プロセスを強制終了するには、メソッドを呼び出すだけです。
yourProcess.terminate() # kill the process!
Pythonはプロセスを強制終了します(UNIXではSIGTERMシグナルを使用し、WindowsではTerminateProcess()
呼び出しを使用)。キューまたはパイプの使用中は注意してください。(それはキュー/パイプのデータを破壊するかもしれません)
なお、multiprocessing.Event
及びmultiprocessing.Semaphore
正確に同じように仕事threading.Event
とthreading.Semaphore
それぞれ。実際、最初のものは後者のクローンです。
本当にスレッドを使用する必要がある場合、直接それを殺す方法はありません。ただし、できることは、「デーモンスレッド」を使用することです。実際、Pythonでは、スレッドにデーモンのフラグを立てることができます。
yourThread.daemon = True # set the Thread as a "daemon thread"
デーモン以外の生きているスレッドがなくなると、メインプログラムは終了します。つまり、メインスレッド(もちろん、非デーモンスレッド)がその操作を完了すると、まだいくつかのデーモンスレッドが動作していても、プログラムは終了します。
メソッドが呼び出されるdaemon
前にスレッドを設定する必要があることに注意してくださいstart()
!
もちろん、daemon
でも使用でき、使用する必要がありますmultiprocessing
。ここでは、メインプロセスが終了すると、そのデーモンプロセスの子プロセスをすべて終了しようとします。
最後に、注意してください。これは選択肢sys.exit()
でos.kill()
はありません。
スレッドを終了するスレッドにトレースをインストールすると、スレッドを強制終了できます。1つの可能な実装については、添付のリンクを参照してください。
あなたが明示的に呼び出している場合はtime.sleep()
、あなたのスレッドの一部(ポーリングいくつかの外部サービスと言う)として、フィリップの方法に改善がでタイムアウトを使用することですevent
さんwait()
どこ方法sleep()
例えば:
import threading
class KillableThread(threading.Thread):
def __init__(self, sleep_interval=1):
super().__init__()
self._kill = threading.Event()
self._interval = sleep_interval
def run(self):
while True:
print("Do Something")
# If no kill signal is set, sleep for the interval,
# If kill signal comes in while sleeping, immediately
# wake up and handle
is_killed = self._kill.wait(self._interval)
if is_killed:
break
print("Killing Thread")
def kill(self):
self._kill.set()
それを実行するには
t = KillableThread(sleep_interval=5)
t.start()
# Every 5 seconds it prints:
#: Do Something
t.kill()
#: Killing Thread
イベントwait()
をsleep()
ingして定期的にチェックする代わりにを使用する利点は、より長いスリープ間隔でプログラムできること、スレッドがほとんど即座に停止すること(そうでなければsleep()
ingしている場合)、そして私の意見では、exitを処理するためのコードは非常に簡単です。 。
Thread.stop
次のコード例に示すように、メソッドを実装することは間違いなく可能です。
import sys
import threading
import time
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()
###############################################################################
def main():
test1 = Thread2(target=printer)
test1.start()
time.sleep(1)
test1.stop()
test1.join()
test2 = Thread2(target=speed_test)
test2.start()
time.sleep(1)
test2.stop()
test2.join()
test3 = Thread3(target=speed_test)
test3.start()
time.sleep(1)
test3.stop()
test3.join()
def printer():
while True:
print(time.time() % 1)
time.sleep(0.1)
def speed_test(count=0):
try:
while True:
count += 1
except StopThread:
print('Count =', count)
if __name__ == '__main__':
main()
Thread3
クラスは約33%よりも速くコードを実行するように見えるThread2
クラス。
self.__stop
、スレッドに設定されているかどうかのチェックを挿入する賢い方法です。ここでの他のほとんどのソリューションと同様に、トレース関数は新しいローカルスコープに入るときにのみ呼び出されるため、実際にはブロッキング呼び出しを中断しません。また注目に値するのは、sys.settrace
デバッガーやプロファイルなどを実装するためのものであり、CPythonの実装の詳細と見なされ、他のPython実装に存在することが保証されていないことです。
Thread2
クラスの最大の問題の1つは、コードの実行が約10倍遅くなることです。一部の人々はまだこれが許容できると思うかもしれません。
from ctypes import *
pthread = cdll.LoadLibrary("libpthread-2.15.so")
pthread.pthread_cancel(c_ulong(t.ident))
tはあなたですThread
オブジェクトです。
Pythonソース(Modules/threadmodule.c
およびPython/thread_pthread.h
)を読んThread.ident
で、pthread_t
型であることを確認pthread
できるので、Pythonを使用して何でもできるようになりますlibpthread
。
スレッドを強制終了するには、次の回避策を使用できます。
kill_threads = False
def doSomething():
global kill_threads
while True:
if kill_threads:
thread.exit()
......
......
thread.start_new_thread(doSomething, ())
これは、別のモジュールでコードが記述されているスレッドをメインスレッドから終了する場合にも使用できます。そのモジュールでグローバル変数を宣言し、それを使用してそのモジュールで生成されたスレッドを終了できます。
私は通常、これを使用して、プログラムの終了時にすべてのスレッドを終了します。これはスレッドを終了する完璧な方法ではないかもしれませんが、役立つかもしれません。
私はこのゲームにかなり遅れていますが、同様の質問に取り組んでおり、次のように問題を完全に解決し、デーモン化されたサブスレッドが終了したときに基本的なスレッド状態のチェックとクリーンアップを実行できます。
import threading
import time
import atexit
def do_work():
i = 0
@atexit.register
def goodbye():
print ("'CLEANLY' kill sub-thread with value: %s [THREAD: %s]" %
(i, threading.currentThread().ident))
while True:
print i
i += 1
time.sleep(1)
t = threading.Thread(target=do_work)
t.daemon = True
t.start()
def after_timeout():
print "KILL MAIN THREAD: %s" % threading.currentThread().ident
raise SystemExit
threading.Timer(2, after_timeout).start()
収量:
0
1
KILL MAIN THREAD: 140013208254208
'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568]
SystemExit
で発生すると、なぜafter_timeout
メインスレッドに対して何かが行われるのですか(この例では、前のスレッドが終了するのを単に待機しています)。
SystemExit
特別なプロパティは2つだけです。トレースバックを生成せず(スレッドを1つスローして終了した場合)、メインスレッドが1つスローして終了した場合は、終了ステータスを設定します(それでも他の非デーモンスレッドを待機しています)。出る)。
追加したいことの1つは、スレッド化lib Pythonの公式ドキュメントを読む場合、Paolo Rovelliが言及したフラグを使用してスレッドを突然終了させたくない場合は、「悪魔的」スレッドの使用を避けることをお勧めします。
公式ドキュメントから:
デーモンスレッドはシャットダウン時に突然停止します。それらのリソース(開いているファイル、データベーストランザクションなど)が適切に解放されない可能性があります。スレッドを適切に停止する場合は、スレッドをデーモン以外にして、イベントなどの適切なシグナルメカニズムを使用します。
デーモンスレッドの作成はアプリケーションに依存すると思いますが、一般的に(そして私の意見では)、スレッドを強制終了したりデーモンにしたりすることは避けた方がよいでしょう。マルチプロセッシングでは、is_alive()
してプロセスのステータスをチェックし、終了するために「終了」することができます(GILの問題も回避できます)。ただし、Windowsでコードを実行すると、さらに多くの問題が見つかることがあります。
また、「ライブスレッド」がある場合は、Pythonインタープリターが待機して実行されることを忘れないでください。(このデーモンが突然問題でなくてもあなたを助けることができるので)。
この目的のために構築されたライブラリstopitがあります。ここに記載されているものと同じ注意事項の一部が依然として適用されますが、少なくともこのライブラリは、指定された目標を達成するための定期的で反復可能な手法を提供します。
それはかなり古いですが、これは一部にとって便利な解決策かもしれません:
スレッディングのモジュール機能を拡張する小さなモジュール。あるスレッドが別のスレッドのコンテキストで例外を発生させることができます。を上げると
SystemExit
、ようやくPythonスレッドを強制終了できます。
import threading
import ctypes
def _async_raise(tid, excobj):
res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(excobj))
if res == 0:
raise ValueError("nonexistent thread id")
elif res > 1:
# """if it returns a number greater than one, you're in trouble,
# and you should call it again with exc=NULL to revert the effect"""
ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
raise SystemError("PyThreadState_SetAsyncExc failed")
class Thread(threading.Thread):
def raise_exc(self, excobj):
assert self.isAlive(), "thread must be started"
for tid, tobj in threading._active.items():
if tobj is self:
_async_raise(tid, excobj)
return
# the thread was alive when we entered the loop, but was not found
# in the dict, hence it must have been already terminated. should we raise
# an exception here? silently ignore?
def terminate(self):
# must raise the SystemExit type, instead of a SystemExit() instance
# due to a bug in PyThreadState_SetAsyncExc
self.raise_exc(SystemExit)
そのため、「スレッドが別のスレッドのコンテキストで例外を発生させる」ことが可能になり、このようにして、終了したスレッドは定期的に中止フラグをチェックしなくても終了を処理できます。
ただし、元のソースによると、このコードにはいくつかの問題があります。
- 例外は、Pythonバイトコードを実行するときにのみ発生します。スレッドがネイティブ/組み込みのブロッキング関数を呼び出す場合、実行がPythonコードに戻ったときにのみ例外が発生します。
- 組み込み関数が内部でPyErr_Clear()を呼び出す場合にも問題があり、保留中の例外を効果的にキャンセルします。あなたはそれを再び上げることを試みることができます。
- 安全に発生させることができるのは、例外タイプのみです。例外インスタンスは予期しない動作を引き起こす可能性が高いため、制限されています。
- 例:t1.raise_exc(TypeError( "blah"))ではなく、t1.raise_exc(TypeError))。
- 私見それはバグであり、私はそれを1つとして報告しました。詳細については、 http://mail.python.org/pipermail/python-dev/2006-August/068158.html
- 組み込みのスレッドモジュールでこの関数を公開するように依頼しましたが、ctypesは標準ライブラリ(2.5以降)になり、この
機能は実装に依存しない可能性が低いため、公開されないままになっている可能性があります
。
ピエター・ヒントジェンズ-の創始者の一人ØMQ -project - ØMQを使用して、と言うとロック、ミューテックス、イベントなどのような同期プリミティブを避け、マルチスレッドプログラムを書くためのsanestとsecurest方法です。
http://zguide.zeromq.org/py:all#Multithreading-with-ZeroMQ
これには、子スレッドに作業をキャンセルするように伝えることが含まれます。これは、スレッドにØMQソケットを装備し、キャンセルする必要があることを示すメッセージをそのソケットでポーリングすることによって行われます。
このリンクは、ØMQを使用したマルチスレッドPythonコードの例も提供します。
同じ機能の複数のスレッドが必要であると仮定すると、これはIDHOで停止するための最も簡単な実装です。
import time
from threading import Thread
def doit(id=0):
doit.stop=0
print("start id:%d"%id)
while 1:
time.sleep(1)
print(".")
if doit.stop==id:
doit.stop=0
break
print("end thread %d"%id)
t5=Thread(target=doit, args=(5,))
t6=Thread(target=doit, args=(6,))
t5.start() ; t6.start()
time.sleep(2)
doit.stop =5 #kill t5
time.sleep(2)
doit.stop =6 #kill t6
いいことはここにあります。同じ機能と異なる機能を複数持つことができ、すべてを停止することができます functionname.stop
関数のスレッドを1つだけにする場合は、IDを覚えておく必要はありません。doit.stop
0より大きい場合は停止してください。
@SCBのアイデア(まさに私が必要とするもの)を基にして、カスタマイズされた関数でKillableThreadサブクラスを作成するだけです。
from threading import Thread, Event
class KillableThread(Thread):
def __init__(self, sleep_interval=1, target=None, name=None, args=(), kwargs={}):
super().__init__(None, target, name, args, kwargs)
self._kill = Event()
self._interval = sleep_interval
print(self._target)
def run(self):
while True:
# Call custom function with arguments
self._target(*self._args)
# If no kill signal is set, sleep for the interval,
# If kill signal comes in while sleeping, immediately
# wake up and handle
is_killed = self._kill.wait(self._interval)
if is_killed:
break
print("Killing Thread")
def kill(self):
self._kill.set()
if __name__ == '__main__':
def print_msg(msg):
print(msg)
t = KillableThread(10, print_msg, args=("hello world"))
t.start()
time.sleep(6)
print("About to kill thread")
t.kill()
当然、@ SBCの場合と同様に、スレッドは新しいループが停止して停止するのを待ちません。この例では、スレッドが完了するのをさらに4秒間待つのではなく、「スレッドを終了しようとしています」の直後に「スレッドを強制終了しています」というメッセージが表示されます(すでに6秒間スリープしているため)。
KillableThreadコンストラクタの2番目の引数はカスタム関数です(ここではprint_msg)。Args引数は、ここで関数(( "hello world"))を呼び出すときに使用される引数です。
@Kozyarchukの回答で述べたように、トレースのインストールは機能します。この回答にはコードが含まれていなかったため、すぐに使えるすぐに使える例を次に示します。
import sys, threading, time
class TraceThread(threading.Thread):
def __init__(self, *args, **keywords):
threading.Thread.__init__(self, *args, **keywords)
self.killed = False
def start(self):
self._run = self.run
self.run = self.settrace_and_run
threading.Thread.start(self)
def settrace_and_run(self):
sys.settrace(self.globaltrace)
self._run()
def globaltrace(self, frame, event, arg):
return self.localtrace if event == 'call' else None
def localtrace(self, frame, event, arg):
if self.killed and event == 'line':
raise SystemExit()
return self.localtrace
def f():
while True:
print('1')
time.sleep(2)
print('2')
time.sleep(2)
print('3')
time.sleep(2)
t = TraceThread(target=f)
t.start()
time.sleep(2.5)
t.killed = True
印刷1
した後に停止し2
ます。3
は印刷されません。
プロセスでコマンドを実行してから、プロセスIDを使用してコマンドを強制終了できます。私は2つのスレッド間で同期する必要があり、そのうちの1つはそれ自体では返されません。
processIds = []
def executeRecord(command):
print(command)
process = subprocess.Popen(command, stdout=subprocess.PIPE)
processIds.append(process.pid)
print(processIds[0])
#Command that doesn't return by itself
process.stdout.read().decode("utf-8")
return;
def recordThread(command, timeOut):
thread = Thread(target=executeRecord, args=(command,))
thread.start()
thread.join(timeOut)
os.kill(processIds.pop(), signal.SIGINT)
return;
setDaemon(True)でサブスレッドを開始します。
def bootstrap(_filename):
mb = ModelBootstrap(filename=_filename) # Has many Daemon threads. All get stopped automatically when main thread is stopped.
t = threading.Thread(target=bootstrap,args=('models.conf',))
t.setDaemon(False)
while True:
t.start()
time.sleep(10) # I am just allowing the sub-thread to run for 10 sec. You can listen on an event to stop execution.
print('Thread stopped')
break
これは悪い答えです、コメントを見てください
方法は次のとおりです。
from threading import *
...
for thread in enumerate():
if thread.isAlive():
try:
thread._Thread__stop()
except:
print(str(thread.getName()) + ' could not be terminated'))
数秒待ってから、スレッドを停止してください。また、thread._Thread__delete()
メソッド。
thread.quit()
便利な方法をお勧めします。たとえば、スレッドにソケットがある場合は、ソケットquit()
ハンドルクラスにメソッドを作成し、ソケットを終了して、のthread._Thread__stop()
内部で実行することをお勧めしますquit()
。
_Thread__stop()
だけで、実際にはスレッドを停止しません!絶対にしないでください。読んでください。
サブタスクを強制終了する機能が本当に必要な場合は、別の実装を使用してください。multiprocessing
そして、gevent
どちらも「スレッド」を無差別に削除することをサポートしています。
Pythonのスレッドはキャンセルをサポートしていません。試しさえしないでください。コードがデッドロックしたり、メモリが破損したりリークしたりする可能性が非常に高くなります。または、まれに非決定的に発生する、デバッグが困難な意図しない「興味深い」効果が発生する可能性があります。