python - 从 Python 中的段错误中恢复
问题描述
我的代码中有一些随机导致SegmentationFault
错误的函数。我已经通过启用faulthandler
. 我有点卡住了,不知道如何可靠地消除这个问题。
我正在考虑一些解决方法。由于这些功能随机崩溃,我可能会在失败后重试它们。问题是没有办法从SegmentationFault
崩溃中恢复。
我现在最好的想法是稍微重写这些函数并通过子进程运行它们。该解决方案将对我有所帮助,崩溃的函数不会使整个应用程序崩溃,并且可以重试。
一些功能非常小并且经常执行,因此它会显着降低我的应用程序的速度。是否有任何方法可以在单独的上下文中执行函数,比在发生段错误时不会使整个程序崩溃的子进程更快?
解决方案
我有一些不可靠的 C 扩展每隔一段时间就会抛出段错误,因为我无法解决这个问题,所以我所做的是创建一个装饰器,它将在单独的进程中运行包装的函数。这样你就可以阻止段错误杀死主进程。
像这样的东西: https ://gist.github.com/joezuntz/e7e7764e5b591ed519cfd488e20311f1
我的有点简单,它为我完成了这项工作。此外,它还允许您选择超时和默认返回值,以防出现问题:
#! /usr/bin/env python3
# std imports
import multiprocessing as mp
def parametrized(dec):
"""This decorator can be used to create other decorators that accept arguments"""
def layer(*args, **kwargs):
def repl(f):
return dec(f, *args, **kwargs)
return repl
return layer
@parametrized
def sigsev_guard(fcn, default_value=None, timeout=None):
"""Used as a decorator with arguments.
The decorated function will be called with its input arguments in another process.
If the execution lasts longer than *timeout* seconds, it will be considered failed.
If the execution fails, *default_value* will be returned.
"""
def _fcn_wrapper(*args, **kwargs):
q = mp.Queue()
p = mp.Process(target=lambda q: q.put(fcn(*args, **kwargs)), args=(q,))
p.start()
p.join(timeout=timeout)
exit_code = p.exitcode
if exit_code == 0:
return q.get()
logging.warning('Process did not exit correctly. Exit code: {}'.format(exit_code))
return default_value
return _fcn_wrapper
所以你会像这样使用它:
@sigsev_guard(default_value=-1, timeout=60)
def your_risky_function(a,b,c,d):
...
推荐阅读
- php - Codeigniter:如何在 JOIN 查询中包含 SUM() 和 COUNT()?
- c - 不断提示用户,直到提供有效值-while 循环 c 编程
- python - Scipy(最初为 Hessian 提供了来自 scipy 的后续 Hessian)
- css - 伪元素的默认样式与它们各自的原始元素的样式是否不同?
- forms - 从现有实体 Symfony4 生成表单
- javascript - 如何在反应应用程序中预取视频?
- matlab - 绘制作为时间函数的自相关
- android - 无法从 Android 模拟器访问 Rails-API-Server
- python - 如何在 Python 中以编程方式启动 appium 服务器
- python - uWSGI Emperor 不会通过触摸 .ini 文件来重新加载 Vassal