Is there a way to kill Thread in Python?

Asked 2 years ago, Updated 2 years ago, 109 views

Is there a way to kill the currently working thread without using flags or semaphores?

multithreading python kill terminate

2022-09-21 17:13

1 Answers

In general, suddenly killing threads is a bad pattern in Python and other languages. Consider the following cases:

* Thread is using critical resources that should be properly closed
* Threads have created multiple threads to kill together

When managing threads, a good approach to addressing this is to have the exit_request flag to see if each thread should shut itself down at regular intervals.

For example:

import threading

class StoppableThread(threading.Thread):
    Thread class with ""stop() method.
    The status of stopped() should be checked regularly on the thread itself."""

    def __init__(self):
        super(StoppableThread, self).__init__()
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

In this code, if you want to terminate the thread, you must call the stop() function and wait for the thread to terminate normally using the join() function. To do that, the thread must check the stop flag every certain time.

But sometimes it's necessary to kill the thread right away. One example is when you need to use an external library that is busy with a long call time, and want to interrupt it.

The code below makes an exception (although some restrictions exist) in Python threads:

def _async_raise(tid, exctype):
    """Exception to Thread Using tid"""
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid,
                                                  ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        # "If you return a number greater than one, there's a problem.
        # In this case, you must call the exc=NULL state again to resolve the issue."
        ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class ThreadWithExc(threading.Thread):
    '''Thread class generating exceptions with other threads
    '''
    def _get_my_tid(self):
        Function that determines """magnetic tid

        CAUTION: This function is used to verify the identity of the instance
        Function used by threads that invoke that 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: Python 2.6 has a simpler method: self.ident

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

    def raiseExc(self, exctype):
        Function for generating a given exception type in the ""thread itself.

        If a system call (time.sleep(), socket.accept(), ...) is made,
        If the thread is busy, exceptions can be ignored.

        If an exception should be used to terminate the threadCotton
        This can be done in the following ways:

            t = ThreadWithExc( ... )
            ...
            t.raiseExc( SomeException )
            while t.isAlive():
                time.sleep( 0.1 )
                t.raiseExc( SomeException )

        If an exception is caught by a thread, then the thread has caught the exception
        We need a way to check.

        CAUTION: This function is used to verify the identity of the instance
        Function used by threads that invoke that instance.
        """
        _async_raise( self._get_my_tid(), exctype )

As shown in the document, if the thread is busy outside the Python interrupt, this is not the perfect method because it cannot catch the interrupt.

A good usage pattern for this code is for threads to catch specific exceptions and perform cleanup operations. This allows you to interrupt the operation and allow normal cleanup.


2022-09-21 17:13

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.