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

标签 python c numpy python-c-api

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

#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;
}

上面的程序在我的两个测试系统(ubuntu 和 manjaro,无论我使用什么 python 版本)上崩溃,并在执行 import numpy 时出现段错误时间。

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

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

最佳答案

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

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

作为替代方案,如果您使用的是类似 UNIX 的机器(即除 Windows 之外的任何机器),则可以通过不同的方式来完成“重置”,即通过 exec 执行您的程序来重新标记它与新的运行。这比 Python 本身的重置更彻底,但即便如此,它也不是万无一失的。例如如果文件描述符未在 O_CLOEXEC 模式下打开,它们将在新的 exec 进程中保持打开状态。

关于多次初始化时,Python C API 在 'import numpy' 处崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59314230/

相关文章:

python - Peewee 无需外键插入

python - 包含空(或无)元素的随机列表

python - to_excel() read_excel() 出现 Pandas Unicode 导入导出错误

python - 如何在 numpy 中将 OpenCV cvMat 转换回 ndarray ?

python - 如何在 numpy 中堆叠数组和标量?

Python和ftplib,无法登录?

C 中的字符矩阵声明和打印

c - 交换 2 个字节的整数

c - C 中的汇编 - 向后打印特定单词

python - 如何使用 isinstance 测试所有可能的整数类型