ホームページ > バックエンド開発 > Python チュートリアル > Python でスレッドを正常に終了する方法と、強制終了が必要な場合は?

Python でスレッドを正常に終了する方法と、強制終了が必要な場合は?

DDD
リリース: 2024-12-28 15:34:19
オリジナル
654 人が閲覧しました

How to Gracefully Terminate Threads in Python, and When is Forced Termination Necessary?

スレッドの正常な終了

スレッドを突然終了することは、特に Python では一般的に推奨されません。重要な操作が中断されると、リソース リークやデータ破損が発生する可能性があります。

推奨されるアプローチ

推奨される方法は、スレッドが中断されていることを示すフラグまたはセマフォを設定することです。終了する必要があります。スレッドはこのフラグを定期的にチェックし、フラグが設定されている場合は正常に終了する必要があります。

例:

import threading

class StoppableThread(threading.Thread):
    def __init__(self,  *args, **kwargs):
        super().__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() を使用して正常に終了するのを待ちます。

強制終了

例外的なケースとして、スレッドを強制的に終了する必要がある場合があります。ただし、これは最後の手段として考えてください。

強制終了のメソッド:

import ctypes
import inspect

def _async_raise(tid, exctype):
    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:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class ThreadWithExc(threading.Thread):
    def _get_my_tid(self):
        if not self.is_alive(): # Note: self.isAlive() on older version of Python
            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

        raise AssertionError("could not determine the thread's id")

    def raise_exc(self, exctype):
        _async_raise(self._get_my_tid(), exctype )
ログイン後にコピー

このメソッドは、PyThreadState_SetAsyncExc 関数に依存して特定の例外を発生させます。糸。ただし、このメソッドは完全に信頼できるわけではなく、スレッドが Python インタプリタの外部のシステム コールにある場合は失敗する可能性があることに注意することが重要です。

注意:

  • このメソッドの使用はできる限り避けてください。
  • 必要に応じて、スレッド固有のクリーンアップ ロジックを実装してデータを確保します。整合性。
  • 潜在的なリスクと制限を理解した上で、この方法は慎重に使用してください。

以上がPython でスレッドを正常に終了する方法と、強制終了が必要な場合は?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート