import threading
class StoppableThread(threading.Thread):"""Thread class with a stop() method. The thread itself has to checkregularly 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()
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 fromanother thread.'''def _get_my_tid(self):"""determines this (self's) thread id
CAREFUL: this function is executed in the context of the callerthread, to get the identity of the thread represented by thisinstance."""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 dictfor tid, tobj in threading._active.items():if tobj is self:self._thread_id = tidreturn 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 raiseExc(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.raiseExc( SomeException )while t.isAlive():time.sleep( 0.1 )t.raiseExc( SomeException )
If the exception is to be caught by the thread, you need a way tocheck that your thread has caught it.
CAREFUL: this function is executed in the context of thecaller thread, to raise an exception in the context of thethread represented by this instance."""_async_raise( self._get_my_tid(), exctype )
from threading import *
...
for thread in enumerate():if thread.isAlive():try:thread._Thread__stop()except:print(str(thread.getName()) + ' could not be terminated'))
import ctypes
def terminate_thread(thread):"""Terminates a python thread from another thread.
:param thread: a threading.Thread instance"""if not thread.isAlive():return
exc = ctypes.py_object(SystemExit)res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(thread.ident), exc)if res == 0:raise ValueError("nonexistent 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(thread.ident, None)raise SystemError("PyThreadState_SetAsyncExc failed")
def bootstrap(_filename):mb = ModelBootstrap(filename=_filename) # Has many Daemon threads. All get stopped automatically when main thread is stopped.
t = threading.Thread(target=bootstrap,args=('models.conf',))t.setDaemon(False)
while True:t.start()time.sleep(10) # I am just allowing the sub-thread to run for 10 sec. You can listen on an event to stop execution.print('Thread stopped')break
import threadingimport ctypes
def _async_raise(tid, excobj):res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(excobj))if res == 0:raise ValueError("nonexistent 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(tid, 0)raise SystemError("PyThreadState_SetAsyncExc failed")
class Thread(threading.Thread):def raise_exc(self, excobj):assert self.isAlive(), "thread must be started"for tid, tobj in threading._active.items():if tobj is self:_async_raise(tid, excobj)return
# the thread was alive when we entered the loop, but was not found# in the dict, hence it must have been already terminated. should we raise# an exception here? silently ignore?
def terminate(self):# must raise the SystemExit type, instead of a SystemExit() instance# due to a bug in PyThreadState_SetAsyncExcself.raise_exc(SystemExit)
import threading
class KillableThread(threading.Thread):def __init__(self, sleep_interval=1):super().__init__()self._kill = threading.Event()self._interval = sleep_interval
def run(self):while True:print("Do Something")
# If no kill signal is set, sleep for the interval,# If kill signal comes in while sleeping, immediately# wake up and handleis_killed = self._kill.wait(self._interval)if is_killed:break
print("Killing Thread")
def kill(self):self._kill.set()
然后运行它
t = KillableThread(sleep_interval=5)t.start()# Every 5 seconds it prints:#: Do Somethingt.kill()#: Killing Thread
from threading import Thread, Event
class KillableThread(Thread):def __init__(self, sleep_interval=1, target=None, name=None, args=(), kwargs={}):super().__init__(None, target, name, args, kwargs)self._kill = Event()self._interval = sleep_intervalprint(self._target)
def run(self):while True:# Call custom function with argumentsself._target(*self._args)
# If no kill signal is set, sleep for the interval,# If kill signal comes in while sleeping, immediately# wake up and handleis_killed = self._kill.wait(self._interval)if is_killed:break
print("Killing Thread")
def kill(self):self._kill.set()
if __name__ == '__main__':
def print_msg(msg):print(msg)
t = KillableThread(10, print_msg, args=("hello world"))t.start()time.sleep(6)print("About to kill thread")t.kill()
from signal import pthread_kill, SIGTSTPfrom threading import Threadfrom itertools import countfrom time import sleep
def target():for num in count():print(num)sleep(1)
thread = Thread(target=target)thread.start()sleep(5)pthread_kill(thread.ident, SIGTSTP)