It is generally a bad pattern to kill a thread abruptly, in Python, and in any language. Think of the following cases:

  • the thread is holding a critical resource that must be closed properly
  • the thread has created several other threads that must be killed as well.

The nice way of handling this, if you can afford it (if you are managing your own threads), is to have an exit_request flag that each thread checks on a regular interval to see if it is time for it to exit.

For example:

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()

In this code, you should call stop() on the thread when you want it to exit, and wait for the thread to exit properly using join(). The thread should check the stop flag at regular intervals.

There are cases, however, when you really need to kill a thread. An example is when you are wrapping an external library that is busy for long calls, and you want to interrupt it.

The following code allows (with some restrictions) to raise an Exception in a Python thread:

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 an 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.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

        # TODO: in python 2.6, there's a simpler way to do: self.ident

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

    def raise_exc(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.raise_exc( SomeException )
            while t.isAlive():
                time.sleep( 0.1 )
                t.raise_exc( 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 exception in the context of the
        thread represented by this instance.
        """
        _async_raise( self._get_my_tid(), exctype )

(Based on Killable Threads by Tomer Filiba. The quote about the return value of PyThreadState_SetAsyncExc appears to be from an old version of Python.)

As noted in the documentation, this is not a magic bullet because if the thread is busy outside the Python interpreter, it will not catch the interruption.

A good usage pattern of this code is to have the thread catch a specific exception and perform the cleanup. That way, you can interrupt a task and still have proper cleanup.

Answer from Philippe F on Stack Overflow
Top answer
1 of 16
880

It is generally a bad pattern to kill a thread abruptly, in Python, and in any language. Think of the following cases:

  • the thread is holding a critical resource that must be closed properly
  • the thread has created several other threads that must be killed as well.

The nice way of handling this, if you can afford it (if you are managing your own threads), is to have an exit_request flag that each thread checks on a regular interval to see if it is time for it to exit.

For example:

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()

In this code, you should call stop() on the thread when you want it to exit, and wait for the thread to exit properly using join(). The thread should check the stop flag at regular intervals.

There are cases, however, when you really need to kill a thread. An example is when you are wrapping an external library that is busy for long calls, and you want to interrupt it.

The following code allows (with some restrictions) to raise an Exception in a Python thread:

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 an 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.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

        # TODO: in python 2.6, there's a simpler way to do: self.ident

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

    def raise_exc(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.raise_exc( SomeException )
            while t.isAlive():
                time.sleep( 0.1 )
                t.raise_exc( 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 exception in the context of the
        thread represented by this instance.
        """
        _async_raise( self._get_my_tid(), exctype )

(Based on Killable Threads by Tomer Filiba. The quote about the return value of PyThreadState_SetAsyncExc appears to be from an old version of Python.)

As noted in the documentation, this is not a magic bullet because if the thread is busy outside the Python interpreter, it will not catch the interruption.

A good usage pattern of this code is to have the thread catch a specific exception and perform the cleanup. That way, you can interrupt a task and still have proper cleanup.

2 of 16
201

A multiprocessing.Process can p.terminate()

In the cases where I want to kill a thread, but do not want to use flags/locks/signals/semaphores/events/whatever, I promote the threads to full blown processes. For code that makes use of just a few threads the overhead is not that bad.

E.g. this comes in handy to easily terminate helper "threads" which execute blocking I/O

The conversion is trivial: In related code replace all threading.Thread with multiprocessing.Process and all queue.Queue with multiprocessing.Queue and add the required calls of p.terminate() to your parent process which wants to kill its child p

See the Python documentation for multiprocessing.

Example:

import multiprocessing
proc = multiprocessing.Process(target=your_proc_function, args=())
proc.start()
# Terminate the process
proc.terminate()  # sends a SIGTERM
🌐
Python.org
discuss.python.org › python help
How kill a Thread? - Python Help - Discussions on Python.org
January 11, 2024 - Hi, when I try this example from: ... is running") time.sleep(10) print("Thread is done") my_thread = threading.Thread(target=my_function) my_thread.start() my_thread.join(5) print("Thread is killed") ......
🌐
Python
docs.python.org › 3 › library › threading.html
threading — Thread-based parallelism — Python 3.14.4 ...
Python’s Thread class supports a subset of the behavior of Java’s Thread class; currently, there are no priorities, no thread groups, and threads cannot be destroyed, stopped, suspended, resumed, or interrupted.
🌐
Miguel Grinberg
blog.miguelgrinberg.com › post › how-to-kill-a-python-thread
How to Kill a Python Thread - miguelgrinberg.com
October 19, 2020 - @Miguel: Well, threads cannot be killed, so your question as posted does not make sense. If you mean to ask what happens with threads that you do not gracefully stop, then it really depends. If the thread is configured as a daemon thread, it will just stop running abruptly when the Python process ends.
🌐
Alexandra Zaharia
alexandra-zaharia.github.io › posts › how-to-stop-a-python-thread-cleanly
How to stop a Python thread cleanly | Alexandra Zaharia
December 31, 2021 - Notice that when the thread is stopped it now finally gets to the print('Thread done') line (a placeholder for an actual cleanup task). Moreover, the main program also gets to the print('Program done') line. Clean exit from a thread can therefore be achieved using a threading event and a signal handler. ... This post is licensed under CC BY 4.0 by the author. ... Concurrency crash course. Part 1: Terminology, usage and pitfalls ... The problem Suppose you have a Python thread that runs your target function.
🌐
Instructables
instructables.com › design › software
Starting and Stopping Python Threads With Events in Python Threading Module. : 4 Steps - Instructables
March 5, 2024 - Starting and Stopping Python Threads With Events in Python Threading Module.: In this instructable, we'll walk through how to use Python's threading module to start and stop threads using events. Threads are a way to execute multiple tasks concurrently within a single process Multithreading ...
🌐
GeeksforGeeks
geeksforgeeks.org › python › python-different-ways-to-kill-a-thread
Python | Different ways to kill a Thread - GeeksforGeeks
July 11, 2025 - Set/Reset stop flag : In order to kill a threads, we can declare a stop flag and this flag will be check occasionally by the thread. For Example ... # Python program showing # how to kill threads # using set/reset stop # flag import threading ...
Find elsewhere
🌐
Python.org
discuss.python.org › ideas
Making it simpler to gracefully exit threads - Ideas - Discussions on Python.org
September 18, 2023 - Currently, telling a thread to gracefully exit requires setting up some custom signaling mechanism, for example via a threading.Event. To make this process a bit more efficient, cleaner and simpler, what if some methods were added to: Set a soft interruption flag for a specific thread, such as threading.Thread.interrupt.
🌐
O'Reilly
oreilly.com › library › view › python-cookbook › 0596001673 › ch06s03.html
Terminating a Thread - Python Cookbook [Book]
July 19, 2002 - """ self._stopevent.set( ) threading.Thread.join(self, timeout) if _ _name_ _ == "_ _main_ _": testthread = TestThread( ) testthread.start( ) import time time.sleep(10.0) testthread.join( ) Often, you will want to control a thread from the outside, but the ability to kill it is, well, overkill. Python doesn’t give you this ability, and thus forces you to design your thread systems more carefully.
Authors   Alex MartelliDavid Ascher
Published   2002
Pages   608
Top answer
1 of 8
172

Threaded stoppable function

Instead of subclassing threading.Thread, one can modify the function to allow stopping by a flag.

We need an object, accessible to running function, to which we set the flag to stop running.

We can use threading.currentThread() object.

import threading
import time


def doit(arg):
    t = threading.currentThread()
    while getattr(t, "do_run", True):
        print ("working on %s" % arg)
        time.sleep(1)
    print("Stopping as you wish.")


def main():
    t = threading.Thread(target=doit, args=("task",))
    t.start()
    time.sleep(5)
    t.do_run = False
    

if __name__ == "__main__":
    main()

The trick is, that the running thread can have attached additional properties. The solution builds on assumptions:

  • the thread has a property "do_run" with default value True
  • driving parent process can assign to started thread the property "do_run" to False.

Running the code, we get following output:

$ python stopthread.py                                                        
working on task
working on task
working on task
working on task
working on task
Stopping as you wish.

Pill to kill - using Event

Other alternative is to use threading.Event as function argument. It is by default False, but external process can "set it" (to True) and function can learn about it using wait(timeout) function.

We can wait with zero timeout, but we can also use it as the sleeping timer (used below).

def doit(stop_event, arg):
    while not stop_event.wait(1):
        print ("working on %s" % arg)
    print("Stopping as you wish.")


def main():
    pill2kill = threading.Event()
    t = threading.Thread(target=doit, args=(pill2kill, "task"))
    t.start()
    time.sleep(5)
    pill2kill.set()
    t.join()

Edit: I tried this in Python 3.6. stop_event.wait() blocks the event (and so the while loop) until release. It does not return a boolean value. Using stop_event.is_set() works instead.

Stopping multiple threads with one pill

Advantage of pill to kill is better seen, if we have to stop multiple threads at once, as one pill will work for all.

The doit will not change at all, only the main handles the threads a bit differently.

def main():
    pill2kill = threading.Event()
    tasks = ["task ONE", "task TWO", "task THREE"]

    def thread_gen(pill2kill, tasks):
        for task in tasks:
            t = threading.Thread(target=doit, args=(pill2kill, task))
            yield t

    threads = list(thread_gen(pill2kill, tasks))
    for thread in threads:
        thread.start()
    time.sleep(5)
    pill2kill.set()
    for thread in threads:
        thread.join()
2 of 8
32

This has been asked before on Stack. See the following links:

  • Is there any way to kill a Thread in Python?
  • Stopping a thread after a certain amount of time

Basically you just need to set up the thread with a stop function that sets a sentinel value that the thread will check. In your case, you'll have the something in your loop check the sentinel value to see if it's changed and if it has, the loop can break and the thread can die.

🌐
Python Tutorial
pythontutorial.net › home › python concurrency › how to stop a thread in python
How to Stop a Thread in Python by Examples
June 3, 2023 - To stop a thread, you use the Event class of the threading module. The Event class has an internal thread-safe boolean flag that can be set to True or False.
🌐
Python
docs.python.org › 3 › library › _thread.html
_thread — Low-level threading API — Python 3.14.4 ...
When the function terminates with an unhandled exception, sys.unraisablehook() is called to handle the exception. The object attribute of the hook argument is function. By default, a stack trace is printed and then the thread exits (but other threads continue to run).
🌐
Christopherdavis
christopherdavis.me › blog › threading-basics.html
Python Threading Basics :: python :: Christopher Davis
""" #: The stop event that's shared by this handler and threads. stopper = None #: The pool of worker threads workers = None def __init__(self, stopper, workers): self.stopper = stopper self.workers = workers def __call__(self, signum, frame): """ This will be called by the python signal module https://docs.python.org/3/library/signal.html#signal.signal """ self.stopper.set() for worker in self.workers: worker.join() sys.exit(0)
🌐
Net Informations
net-informations.com › python › iq › kill.htm
Is there any way to kill a Thread in Python?
In Python, you cannot directly kill a thread using built-in methods because it can lead to unpredictable behavior and resource leaks. However, you can stop a thread by setting a flag or condition that the thread checks periodically.
🌐
Quora
quora.com › How-do-you-terminate-a-running-program-with-threads-in-Python
How to terminate a running program with threads in Python - Quora
Give threads a way to detect they should stop (Event, Condition, shared flag). Make thread work loop check the signal at reasonable points and exit cleanly, releasing resources. ... Terminating a running Python program that uses threads requires care: threads cannot be killed forcibly from another thread in the standard library, so use cooperative shutdown patterns, or if needed use process-level termination.
🌐
Super Fast Python
superfastpython.com › home › tutorials › how to stop a thread in python
How to Stop a Thread in Python - Super Fast Python
September 11, 2022 - You can stop a thread by using a threading.Event. In this tutorial you will discover how to gracefully stop a thread in Python. Let’s get started. Need to Stop a Thread A thread is a thread of execution in a computer program. Every Python program has at least one thread of execution called ...
🌐
Delft Stack
delftstack.com › home › howto › python › python kill thread
How to Kill a Python Thread | Delft Stack
February 12, 2024 - Terminating a thread in Python often involves signaling the thread to gracefully exit its execution. One effective and thread-safe approach is using an event mechanism. ... import threading import time class Twe(threading.Thread): def __init__(self, ...
🌐
CodeSpeedy
codespeedy.com › home › different ways to kill a thread in python
Different Ways to Kill a Thread in Python - CodeSpeedy
March 5, 2022 - Using an exit flag to kill a thread in python is easier and more efficient than the other methods. we use an exit flag for each thread so that the thread can know when is the time for them to exit the main program. import threading import time def thread(stop): while True: print("RUNNING") if exitflag1: break exitflag1 = False t1 = threading.Thread(target = thread, args =(lambda : exitflag1, )) t1.start() time.sleep(0.1) print('Stop the threads.') exitflag1 =True t1.join() print('TERMINATED!')