使用Python C API重新启动Python解释器

问题描述 投票:0回答:1

我有一个 C++/Qt 应用程序,我在主应用程序的进程中运行 Python 解释器会话。我构建了一个“python 控制台”作为 QPlainTextEdit 小部件,它使用 Python C API 处理解释器的输入和输出。所有这一切的要点是,Python 将可以直接访问我在主应用程序中保存的数据。一切都很好,除了我希望能够结束当前的解释器会话并重新启动它而不退出主应用程序。

目前,我正在尝试显而易见的方法:

Py_Initialize();
// Run the main session...
Py_FinalizeEx();

// Restart the session
Py_Initialize();

通过阅读其他帖子和Python的文档,由于内存泄漏,在完成解释器后重新加载某些模块可能会出现问题。在我的例子中这似乎是正确的:重新导入某些模块(如“numpy”)而不是其他模块(如“sys”)将触发异常并失败。

是否有一个好的解决策略可以重新启动解释器而不会出现这些问题?例如,如果我生成一个子解释器,完成它并重新启动一个新的子解释器是否会遇到我遇到的相同问题?我试图避免的另一种选择是在进程外运行 Python,我认为这将允许我通过基本上终止进程并启动一个新进程来重新启动。任何策略建议将不胜感激。

python c++ ipc
1个回答
0
投票

来自

Py_FinalizeEx
文档

错误和警告:模块和模块中对象的破坏是 以随机顺序完成;这可能会导致析构函数(del() 方法) 当它们依赖于其他对象(甚至函数)或模块时会失败。 Python 加载的动态加载的扩展模块不是 卸载。 Python解释器分配的少量内存 可能无法释放(如果您发现泄漏,请报告)。内存绑定 对象之间的循环引用没有被释放。一些记忆 由扩展模块分配的空间可能无法释放。一些扩展可能 如果调用它们的初始化例程超过 一次;如果应用程序调用 Py_Initialize() 并且 Py_FinalizeEx() 多次。

特别注意:

某些扩展可能无法正常工作如果它们的初始化例程被调用超过 一次; 如果应用程序调用 Py_Initialize() 并且 Py_FinalizeEx() 多次

(重点是我的)

很明显,设计不支持您尝试的最终确定和重新初始化

因此,建议您初始化 python 引擎一次(当您的进程启动时或第一次需要它时),并且仅在退出时完成它(或者至少当您确定不再需要它时)。

即使您找到了一些适用于特定场景的解决方法,鉴于上述信息,我认为这不是一个好主意。

© www.soinside.com 2019 - 2024. All rights reserved.