Kann die zugrundeliegende Ausführung eines Threads abgebrochen werden, nachdem es wegen Timeout abgebrochen wurde?Python 3: Thread: Töten aufrufbare Ausführung nach Abbruch wegen Timeout?
Ich verfolge den folgenden Threading-Ansatz hier zu finden: Timeout a Python Callable
Eine überarbeitete Version dieses Codes für Python 3 ist unten.
Dieser Code ist Timeout richtig eine aufrufbare Funktion durch ein RuntimeError
werfen, wenn implementiert threading.Thread.abort()
genannt wird, die, wie erwartet, wenn es Timeout-Wert zu threading.Thread.join(timeout)
zugewiesen wurde.
Obwohl der Thread abgebrochen wurde, wird die zugrunde liegende Callable dennoch ausgeführt.
Frage: Wie kann ich diesen Thread beenden, nachdem er abgebrochen wurde, um zu verhindern, dass die zugrunde liegende Callable weiter ausgeführt wird, ohne die übergeordnete ausführbare Datei zu löschen?
Hier ist mein Code:
import datetime as dt
import threading
def run_command_with_threaded_timeout(
func,
fargs=None,
fkwargs=None,
threaded_run_timeout_secs=None
):
class TimedThread(threading.Thread):
"""An abortable thread, by raising an exception inside its
context.
"""
def __init__(self):
super(TimedThread, self).__init__()
self.exc_info = (None, None, None)
def run(self):
self.started_at = dt.datetime.now()
try:
args = fargs if fargs else list()
kwargs = fkwargs if fkwargs else dict()
request_func = partial(func, *args, **kwargs)
self.result = request_func()
except:
# save the exception as an object attribute
self.exc_info = sys.exc_info()
self.result = None
self.ended_at = dt.datetime.now()
def abort(self):
self.ended_at = dt.datetime.now()
threaded_run_diff = self.ended_at - self.started_at
threaded_run_diff_secs = threaded_run_diff.seconds
if threaded_run_diff_secs >= threaded_run_timeout_secs:
raise RuntimeError(
"Threaded Run: Timed Out"
)
raise RuntimeError(
"Threaded Run: Aborted"
)
t = TimedThread()
t.start()
t.join(timeout=threaded_run_timeout_secs)
if t.exc_info[0] is not None: # if there were any exceptions
exc_type, exc_value, exc_traceback = t.exc_info
# Raise the exception/traceback inside the caller
raise exc_type.with_traceback(exc_value, exc_traceback)
if t.is_alive():
t.abort()
diff = t.ended_at - t.started_at
raise RuntimeError("%(f)s timed out after %(d)r seconds" %
{'f': func, 'd': diff.seconds})
return t.result