gpt4 book ai didi

python - 奇怪的进程因 boost.python 而失败

转载 作者:太空宇宙 更新时间:2023-11-04 11:33:01 24 4
gpt4 key购买 nike

我使用 boost.python 来调用脚本。每个 python 脚本有 3 个函数:

  • 初始化 - 必须在开始时调用
  • Uninitialize - 必须在结束时调用以关闭每个对象。
  • 进程 - 必须在初始化和取消初始化之间多次调用。

这个类不需要解释:

class PyInit
{
public:
PyInit() { Py_Initialize(); }
~PyInit() { Py_Finalize(); }
};

此类创建 PyInit 对象实例,然后初始化所有 Python 对象并在构造函数中调用“Initialize()”python 函数。并在析构函数中调用“Uninitialize()”。

并且这个类有函数“Process”可以在类外多次调用它。

class PyGuard
{
public:
explicit PyGuard(const char* pypath)
{
try
{
_main_module = boost::python::import("__main__");
_main_namespace = _main_module.attr("__dict__");
boost::python::object ignored = exec_file(pypath, _main_namespace);
_Initialize = _main_namespace["Initialize"];
_Process = _main_namespace["Process"];
_Uninitialize = _main_namespace["Uninitialize"];

_InitRes = _Initialize();
_ProcRes = boost::python::object();
}
catch(boost::python::error_already_set&)
{
string res;
py_utils::err_parse(res);
throw string("Python exception: " + res);
}
catch(std::exception& e)
{
throw string("C++ exception: " + string(e.what()));
}
catch(...)
{
throw string("Unhandled exception!");
}
}
virtual ~PyGuard()
{
_Uninitialize(_InitRes, _ProcRes);
}
void Process()
{
_ProcRes = _Process(_InitRes, _ProcRes);
}


private:
py_utils::PyInit _initPython;

boost::python::object _InitRes;
boost::python::object _ProcRes;

boost::python::object _Process;
boost::python::object _Initialize;
boost::python::object _Uninitialize;

boost::python::object _main_module;
boost::python::object _main_namespace;
};

由于只有“Process”因“boost::python::error_already_set”异常而失败,因此 PyGuard 的当前实例被删除,然后创建一个新实例。避免可能作为隐藏异常结果的隐藏依赖项。

因此,在异常之后,所有 python 内容都被删除(甚至调用 Py_Finalize()),然后重新创建。

仍然,在 4-10 个这样的异常之后,整个 c++ 进程失败。

跌倒,甚至避开 catch 手:

  try
{
_PyGuard = make_shared<PyGuard>("my script");
while(true)
{
try {
_PyGuard->Process();
}
catch()
{
bool inited = false;
while(!inited)
{
try
{
_pyGuard = nullptr;
_pyGuard = make_shared<PyGuard>("script path.txt");
inited = true;
}
catch(string& e)
{
}
}
}
}
_PyGuard = nullptr;
}
catch(...)
{
//falling, it never being catched here.
}

那么,我的问题是,为什么它会掉下来而且抓不到?

我刚刚发现它落在了直线上:

_pyGuard = make_shared<PyGuard>("script path.txt"); 

call,所以感觉是Python raise exception 抓不到。为什么?又该如何预防?

最佳答案

问题可能出在您对 Py_Finalize() 的使用上。根据 Boost 1.55 文档,您 shouldn't use Py_Finalize() with Boost.Python .看起来您的程序并不真的需要完成,因此您可以尝试从 ~PyInit() 中删除调用。

如果出于某种原因你真的需要完成,你可以看看 Py_NewInterpreter() .

至于您的“无法捕获的异常”问题,这通常是同时具有两个事件异常的结果。当这种情况发生时,C++ 将简单地中止。这可能(也可能不是)您的代码正在发生的事情。

关于python - 奇怪的进程因 boost.python 而失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23889633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com