Abruptly terminating threads is generally regarded as a poor programming technique. Abruptly terminating a thread could potentially expose a vital resource that needs to be appropriately closed. However, once a certain amount of time has elapsed or an interrupt has been generated, you may choose to stop the thread. In Python, you have multiple options to kill a thread in python.
- Raising exceptions in a python thread
- Set/Reset stop flag
- Using traces to kill threads
- Using the multiprocessing module to kill threads
- Killing Python thread by setting it as daemon
- Using a hidden function _stop()
Here are some of the methods to kill a thread in python.
Raising exceptions in a python thread :
This method uses the function PyThreadState_SetAsyncExc() to raise an exception in the a thread.
For Example,
# Python program raising # exceptions in a python # thread import threading import ctypes import time class thread_with_exception(threading.Thread): def __init__(self, name): threading.Thread.__init__(self) self.name = name def run(self): # target function of the thread class try: while True: print('running ' + self.name) finally: print('ended') def get_id(self): # returns id of the respective thread if hasattr(self, '_thread_id'): return self._thread_id for id, thread in threading._active.items(): if thread is self: return id def raise_exception(self): thread_id = self.get_id() res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, ctypes.py_object(SystemExit)) if res > 1: ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, 0) print('Exception raise failure') t1 = thread_with_exception('Thread 1') t1.start() time.sleep(2) t1.raise_exception() t1.join()
You’ll see that the target function run() finishes as soon as the function raise_exception() is called when we run the code above on a computer. This is due to the fact that program control leaves the try block and the run() function is ended as soon as an exception is raised. The thread can then be terminated by calling the join() function. The target function run() never ends and the join() function is never called to end the thread in the absence of the procedure run_exception(). this will kill a thread in python.
Set/Reset stop flag:
We can declare a stop flag, which the thread will periodically check, in order to terminate the thread.
For example,
import threading import time def run(): while True: print('thread running') global stop_threads if stop_threads: break stop_threads = False t1 = threading.Thread(target = run) t1.start() time.sleep(1) stop_threads = True t1.join() print('thread killed')
In the code above, the target function run() terminates as soon as the global variable stop_threads is set, and t1.join() can be used to kill thread t1. But for a variety of reasons, one can choose not to use a global variable.
Using the multiprocessing module to kill threads:
Similar to how you can spawn threads using the threading module, you can spawn processes using Python’s multiprocessing module. The threading module’s and the multithreading module’s interfaces are comparable. For instance, we generated three threads, or processes, with a count of 1 through 9, within a specific code.
import threading import time # counts from 1 to 9 def func(number): for i in range(1, 10): time.sleep(0.01) print('Thread ' + str(number) + ': prints ' + str(number*i)) # creates 3 threads for i in range(0, 3): thread = threading.Thread(target=func, args=(i,)) thread.start()
Despite having a similar interface, the two modules are implemented significantly differently. While processes are totally isolated from one another, all threads share global variables. Therefore, terminating processes is far more secure than terminating threads. A function called terminate() is available to the Process class to end a process. Now, returning to the original issue. Assume that the code above is intended to terminate all processes after 0.03 seconds. The multiprocessing module in the following code is used to accomplish this feature.