问题描述
我最近正在学习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 (将#修改为@)