多次初始化时,Python C API在'import numpy'崩溃

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

[使用Python C API时,我发现python解释器在第二次初始化并在每次初始化后执行import numpy时崩溃。其他任何命令(例如import time)也可以。

#include <Python.h>

int main(int argc, char ** argv)
{
    while(1){
        printf("Initializing python interpreter...\n");
        Py_Initialize();
        if(PyRun_SimpleString("import numpy")) {
            exit(1);
        }
        printf("Finalizing python interpreter...\n");
        Py_Finalize();
    }
    return 0;
}

上面的程序在第二次执行import numpy时在Segmentation Fault的情况下在我的两个测试系统(ubuntu和manjaro,无论我使用的是哪个python版本)上都崩溃了。

文档(https://docs.python.org/3/c-api/init.html?#c.Py_FinalizeEx)确实说:如果某些扩展名的初始化例程被多次调用,它们可能无法正常工作;如果应用程序多次调用Py_Initialize()和Py_FinalizeEx(),则会发生这种情况。

但是不应该有一种方法来正确清除解释器的内存,以便可以多次初始化它吗?例如,如果我有一个允许用户运行自定义python脚本的程序,则应该可以多次运行同一脚本而无需重新启动该程序。有任何线索吗?

python c numpy python-c-api
1个回答
1
投票

您不能仅仅声明应该清除/重置所有内存; Python并不能完全控制它。扩展模块是实际的共享对象/ DLL文件,实际上可以执行普通C程序可以执行的任何操作,并且不需要以核心Python解释器知道how的方式注册所有操作。在完成时撤消它们。 Python无法知道SO / DLL存储器的this部分存储了必须清除的数据,而that部分是静态数据,应该保留下来。

完全有可能多次运行脚本,但是您不必通过最终确定和重新初始化来执行它,您实际上只是在一次初始化中多次运行了脚本(并希望以幂等方式编写)。

或者,如果您使用的是类似UNIX的机器(阅读内容:Windows以外的任何东西),则可以通过exec将程序重新运行以进行重新标记,从而以不同的方式进行“重置”。尽管Python并非万无一失,但它比Python本身能更彻底地进行重置。例如如果未在O_CLOEXEC模式下打开文件描述符,它们将在新的exec版本的进程中保持打开状态。

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