如何解决为什么PyRun_SimpleString不释放内存
我最近正在学习cpython
,并且已经编写了有关我所学内容的守护程序。
首先,我创建自定义PytestClass
类型并将其作为内置模块导入。然后,我调用PyRun_SimpleString
运行使用PytestClass
的脚本,但是我发现PytestClass
的析构函数直到Py_Finalize都不会被调用。谁能解释这个问题,并且在脚本运行后如何清除内存?我担心内存泄漏。
#include "Python.h"
#include <stdio.h>
#include <unistd.h>
#include <stdbool.h>
#include <string.h>
PyMethodDef PyFlatExecutionMethods[] = {
{NULL,NULL,NULL}
};
typedef struct PytestExecution {
PyObject_HEAD
int a;
}PytestExecution;
static PyObject *PytestExecution_ToStr(PyObject * pyObj){
return PyUnicode_FromString("PytestExecution");
}
static void PytestExecution_Destruct(PyObject *pyObj){
//PytestExecution* pfep = (PytestExecution*)pyObj;
printf("PytestExecution_Destruct\n");
Py_TYPE(pyObj)->tp_free((PyObject*)pyObj);
}
static PyTypeObject PytestClass = {
PyVarObject_HEAD_INIT(NULL,0)
"rrunner.PytestExecution",/* tp_name */
sizeof(PytestExecution),/* tp_basicsize */
0,/* tp_itemsize */
PytestExecution_Destruct,/* tp_dealloc */
0,/* tp_print */
0,/* tp_getattr */
0,/* tp_setattr */
0,/* tp_compare */
0,/* tp_repr */
0,/* tp_as_number */
0,/* tp_as_sequence */
0,/* tp_as_mapping */
0,/* tp_hash */
0,/* tp_call */
PytestExecution_ToStr,/* tp_str */
0,/* tp_getattro */
0,/* tp_setattro */
0,/* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,/* tp_flags */
"PytestExecution",/* tp_doc */
};
static PyModuleDef EmbrRunner = {
PyModuleDef_HEAD_INIT,"rrunner","export methods provide by rrunner.",-1,NULL
};
static PyObject* PyInit_rRunner(void) {
return PyModule_Create(&EmbrRunner);
}
static PyObject* runnerCtx(PyObject *cls,PyObject *args){
return NULL;
}
PyMethodDef EmbrtestMethods[] = {
{"runnerCtx",runnerCtx,METH_VaraRGS,"runner context"},{NULL,NULL}
};
char *script = "from rrunner import Pytest;\ndef abc():\n\tprint('in abc 1')\nabc()\nbc=Pytest()\nbc.map()\n";
char *script2 = "import sys;\ndef abc():\n\tprint('in abc 2')\nabc()\nbc2=Pytest()";
char *script3 = "import sys;\ndef abc():\n\tprint('in abc 2')\nabc()\nbc3=Pytest()";
char *script4 = "import sys;\ndef abc():\n\tprint('in abc 2')\nabc()\nbc4=Pytest()";
int main()
{
EmbrRunner.m_methods = EmbrtestMethods;
EmbrRunner.m_size = sizeof(EmbrtestMethods) / sizeof(*EmbrtestMethods);
PyImport_AppendInittab("rrunner",&PyInit_rRunner);
Py_Initialize();
PyEval_InitThreads();
PytestClass.tp_new = PyType_GenericNew;
PytestClass.tp_methods = PyFlatExecutionMethods;
if (PyType_Ready(&PytestClass) < 0){
printf("regiester error\n");
return 0;
}
Py_INCREF(&PytestClass);
PyObject *pName = PyUnicode_FromString("rrunner");
PyObject* rRunnerModule = PyImport_Import(pName);
Py_DECREF(pName);
PyModule_Addobject(rRunnerModule,"Pytest",(PyObject *)&PytestClass);
int a = PyRun_SimpleString(script);
a = PyRun_SimpleString(script2);
a = PyRun_SimpleString(script3);
a = PyRun_SimpleString(script4);
printf("After dup run\n");
a = PyRun_SimpleString(script4);
printf("After run\n");
Py_Finalize();
}
此外,我对实现可以运行从客户端发送的脚本的应用程序感兴趣。在cpython
下是否有任何解决方案,我只是想要彼此隔离的脚本(为每个脚本创建一个新的解释器太耗时了)?我发现子解释器可能成为解决方案,但没有找到示例。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。