Is there a way to kill the currently working thread without using flags or semaphores?
multithreading python kill terminate
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.
© 2024 OneMinuteCode. All rights reserved.