Python 3:线程:由于超时而中止后终止可调用执行?
Python 3: Thread: Killing callable execution after Aborted due to Timeout?
线程超时bee abort后是否可以杀死线程底层执行?
我遵循此处提供的以下线程方法:
Timeout a Python Callable
Python3 的此代码的修订版如下。
此代码通过在调用实现 threading.Thread.abort()
时抛出 RuntimeError
来正确超时可调用函数,这与将超时值分配给 threading.Thread.join(timeout)
时的预期一致。
然而,即使线程被中止,底层的可调用对象仍在执行。
问题:如何在线程中止后终止该线程以阻止底层可调用对象继续执行,而不终止父可执行文件?
这是我的代码:
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
我读到的是不能从外部杀死线程。
可以做的是提供一个线程读取的全局,以确定它是否还活着。
global is_alive = True
kwargs = {
'config_job': config_job,
'config_request_params': config_request_params,
'config_request_credentials': config_request_credentials,
'config_request_retry': config_request_retry
}
try:
response = run_command_with_threaded_timeout(
func=cmd,
fargs=None,
fkwargs=kwargs,
timeout_sec=timeout_sec
)
except Exception as ex:
is_alive = False
raise
线程超时bee abort后是否可以杀死线程底层执行?
我遵循此处提供的以下线程方法: Timeout a Python Callable
Python3 的此代码的修订版如下。
此代码通过在调用实现 threading.Thread.abort()
时抛出 RuntimeError
来正确超时可调用函数,这与将超时值分配给 threading.Thread.join(timeout)
时的预期一致。
然而,即使线程被中止,底层的可调用对象仍在执行。
问题:如何在线程中止后终止该线程以阻止底层可调用对象继续执行,而不终止父可执行文件?
这是我的代码:
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
我读到的是不能从外部杀死线程。
可以做的是提供一个线程读取的全局,以确定它是否还活着。
global is_alive = True
kwargs = {
'config_job': config_job,
'config_request_params': config_request_params,
'config_request_credentials': config_request_credentials,
'config_request_retry': config_request_retry
}
try:
response = run_command_with_threaded_timeout(
func=cmd,
fargs=None,
fkwargs=kwargs,
timeout_sec=timeout_sec
)
except Exception as ex:
is_alive = False
raise