Add a bunch of comments to StoppableThread
This commit is contained in:
parent
19497ca229
commit
6bee825db7
@ -8,43 +8,83 @@
|
||||
import os
|
||||
import ctypes
|
||||
import threading
|
||||
import time
|
||||
import sys
|
||||
|
||||
__all__ = ('StoppableThread', 'JoinThread')
|
||||
|
||||
class StoppableThread(threading.Thread):
|
||||
'''
|
||||
StoppableThread - A thread that can be stopped by forcing an exception in the execution context.
|
||||
|
||||
This works both to interrupt code that is in C or in python code, at either the next call to a python function,
|
||||
or the next line in python code.
|
||||
|
||||
It is recommended that if you call stop ( @see StoppableThread.stop ) that you use an exception that inherits BaseException, to ensure it likely isn't caught.
|
||||
|
||||
Also, beware unmarked exception handlers in your code. Code like this:
|
||||
|
||||
while True:
|
||||
try:
|
||||
doSomething()
|
||||
except:
|
||||
continue
|
||||
|
||||
will never be able to abort, because the exception you raise is immediately caught.
|
||||
|
||||
The exception is raised over and over, with a specifed delay (default 2.0 seconds)
|
||||
'''
|
||||
|
||||
|
||||
def _stopThread(self, exception):
|
||||
def _stopThread(self, exception, raiseEvery=2.0):
|
||||
'''
|
||||
_stopThread - @see StoppableThread.stop
|
||||
'''
|
||||
if self.isAlive() is False:
|
||||
return True
|
||||
|
||||
self._stderr = open(os.devnull, 'w')
|
||||
joinThread = JoinThread(self, exception)
|
||||
|
||||
# Create "joining" thread which will raise the provided exception
|
||||
# on a repeat, until the thread stops.
|
||||
joinThread = JoinThread(self, exception, repeatEvery=raiseEvery)
|
||||
|
||||
# Try to prevent spurrious prints
|
||||
joinThread._stderr = self._stderr
|
||||
joinThread.start()
|
||||
joinThread._stderr = self._stderr
|
||||
|
||||
def stop(self, exception):
|
||||
def stop(self, exception, raiseEvery=2.0):
|
||||
'''
|
||||
Stops the thread by raising a given exception.
|
||||
|
||||
@param exception <Exception> - Exception to throw. Likely, you want to use something
|
||||
that inherits from BaseException (so except Exception as e: continue; isn't a problem)
|
||||
'''
|
||||
return self._stopThread(exception)
|
||||
return self._stopThread(exception, raiseEvery)
|
||||
|
||||
|
||||
class JoinThread(threading.Thread):
|
||||
'''
|
||||
JoinThread - The workhouse that stops the StoppableThread
|
||||
JoinThread - The workhouse that stops the StoppableThread.
|
||||
|
||||
Takes an exception, and upon being started immediately raises that exception in the current context
|
||||
of the thread's execution (so next line of python gets it, or next call to a python api function in C code ).
|
||||
|
||||
@see StoppableThread for more details
|
||||
'''
|
||||
|
||||
def __init__(self, otherThread, exception, repeatEvery=2.0):
|
||||
'''
|
||||
__init__ - Create a JoinThread (don't forget to call .start() ! )
|
||||
|
||||
@param otherThread <threading.Thread> - A thread
|
||||
|
||||
@param exception <BaseException> - An exception. Should be a BaseException, to prevent "catch Exception as e: continue" type code
|
||||
from never being terminated. If such code is unavoidable, you can try setting #repeatEvery to a very low number, like .00001,
|
||||
and it will hopefully raise within the context of the catch, and be able to break free.
|
||||
|
||||
@param repeatEvery <float> Default 2.0 - After starting, the given exception is immediately raised. Then, every #repeatEvery seconds,
|
||||
it is raised again, until the thread terminates.
|
||||
'''
|
||||
threading.Thread.__init__(self)
|
||||
self.otherThread = otherThread
|
||||
self.exception = exception
|
||||
@ -52,6 +92,9 @@ class JoinThread(threading.Thread):
|
||||
self.daemon = True
|
||||
|
||||
def run(self):
|
||||
'''
|
||||
run - The thread main. Will attempt to stop and join the attached thread.
|
||||
'''
|
||||
|
||||
# Try to silence default exception printing.
|
||||
self.otherThread._Thread__stderr = self._stderr
|
||||
@ -69,4 +112,4 @@ class JoinThread(threading.Thread):
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# vim: set ts=4 sw=4 expandtab :
|
||||
|
||||
Loading…
Reference in New Issue
Block a user