2. 在Py_Main函数中,初始化函数为Py_Initialize();,而后者直接调用Py_InitializeEx(1);函数;
3. 在Py_InitializeEx函数中,首先判断是否已经初始化过,如果有则返回,没有就改下标志,开始初始化;第一步也是十分关键的一步,是调用函数(interp=PyInterpreterState_New();)创建PyInterpreterState对象(即解释器进程,现在Python一个解释器只有一个进程,所以存在一个缺点,在多核的机子上也只能存在一个进程)。
4. 在PyInterpreterState_New()函数中,首先为PyInterpreterState对象分配内存:
PyInterpreterState*interp=(PyInterpreterState*)
malloc(sizeof(PyInterpreterState));
如果分配内存成功,执行HEAD_INIT();宏:
#ifdefWITH_THREAD
#include"pythread.h"
staticPyThread_type_lockhead_mutex=NULL;/*
Protects interp->tstate_head */
#defineHEAD_INIT()(void)(head_mutex||(head_mutex=PyThread_allocate_lock()))
#defineHEAD_LOCK()PyThread_acquire_lock(head_mutex,WAIT_LOCK)
#defineHEAD_UNLOCK()PyThread_release_lock(head_mutex)
不论是从名称还是注释都可以看出head_mutex是用来保护解释器进程的tstate_head成员的。
在head_mutex为NULL的情况下会调用PyThread_allocate_lock()函数初始化head_mutex变量。
接着初始化其它成员。
于是,解释器进程就这么创建了……
接着立马创建线程:tstate=PyThreadState_New(interp);,继而调用new_threadstate(interp,1);。
同样地,先为线程对象分配空间:PyThreadState*tstate=(PyThreadState*)malloc(sizeof(PyThreadState));。
接着一样是对线程对象进行初始化,然后切换一下线程:(void)PyThreadState_Swap(tstate);。
接下来一步是很重要的,就是初始化类型信息:_Py_ReadyTypes();。
后续初始化顺序如下:
if(!_PyFrame_Init())
Py_FatalError("Py_Initialize:
can't init frames");
if(!_PyInt_Init())
Py_FatalError("Py_Initialize:
can't init ints");
if(!_PyLong_Init())
Py_FatalError("Py_Initialize:
can't init longs");
if(!PyByteArray_Init())
Py_FatalError("Py_Initialize:
can't init bytearray");
_PyFloat_Init();
第一个函数其实就是初始化变量staticPyObject*builtin_object;为字符串“__builtins__”;
第二个函数是初始化小整数的缓存链表,这里的小整数范围是可以自定义再重新编译进行设置的,过程挺有趣的;
第三个函数初始化Long类型信息,第四个函数没做什么;
接着初始化Float类型信息。
然后是初始化interp的modules和modules_reloading成员,都是简单地调用PyDict_New()函数赋值。
如果需要的话,还会初始化Unicode编码:_PyUnicode_Init();。
接着是模块初始化,代码有省略:
bimod=_PyBuiltin_Init();
interp->builtins=PyModule_GetDict(bimod);
interp->sysdict=PyModule_GetDict(sysmod);
还有模块导入机制、异常、警告的初始化,代码有省略:
_PyImport_Init();
initmain();/*
Module __main__ */
初始化全局锁:
/*
auto-thread-state API, if available */
#ifdefWITH_THREAD
_PyGILState_Init(interp,tstate);
#endif/*
WITH_THREAD */
最后是检查stdin,stdout,stderr和设置相关信息。
然后回到Py_Main,输出版本信息以及“>>>”,等用户输入。
假设输入“a = 1”,然后按Enter键:
Python会先对用户输入进行编译(co=PyAST_Compile(mod,filename,flags,arena);),生成PyCodeObject,然后再执行:v=PyEval_EvalCode(co,globals,locals);:
PyObject*
PyEval_EvalCode(PyCodeObject*co,PyObject*globals,PyObject*locals)
{
returnPyEval_EvalCodeEx(co,
globals,locals,
(PyObject**)NULL,0,
(PyObject**)NULL,0,
(PyObject**)NULL,0,
NULL);
}
于是我们最终进入到PyEval_EvalFrameEx函数,在这里用大量的switch/case来执行指令。
相关推荐
自己写的helloworld程序,从最简单c++中调用python函数,捕捉python出错到c++类封装python类的方法都有。
Python 虚拟机框架.pdf Python 虚拟机框架.pdf
适用于CentOS 7服务端Python环境搭建 包括:Python 3.8.7、Nginx 1.19.2 、redis-50.012、mysql-5.7.36 脚本使用了阿里云镜像、华为云镜像,如果部分内网环境下配置,可能需要配置白名单。 默认端口开放:80\3306\22...
batavia, python 虚拟机的JavaScript实现 Batavia Batavia是早期的alpha项目。 如果坏了你就得把那些闪亮的碎片。 Batavia是 python 虚拟机的一个实现,用JavaScript编写。 使用 Batavia,你可以在浏览
Ubuntu系统,使用python的Django框架,做web开发,初始化时需要安装的一些必须包,及安装指令
手把手教您如何使用python语言,创建OpenStack虚拟机。
染色方法在Python虚拟机内存管理中的应用研究
染色方法在Python虚拟机内存管理中的应用研究.pdf
4-4python中初始化实例属性.pdf
——学习参考资料:仅用于个人学习使用! 本代码仅作学习交流,切勿用于商业用途,否则后果自负。若涉及侵权,请联系,会尽快处理! 未进行详尽测试,请自行调试!
Python中初始化一个5 x 3每项为0的数组,最好方法是: multilist = [[0 for col in range(5)] for row in range(3)]我们知道,为了初始化一个一维数组,我们可以这样做: alist = [0] * 5没错,那我们...
初始化Linux操作系统的开发环境相关配置
——学习参考资料:仅用于个人学习使用! 本代码仅作学习交流,切勿用于商业用途,否则后果自负。若涉及侵权,请联系,会尽快处理! 未进行详尽测试,请自行调试!
——学习参考资料:仅用于个人学习使用! 本代码仅作学习交流,切勿用于商业用途,否则后果自负。若涉及侵权,请联系,会尽快处理! 未进行详尽测试,请自行调试!
虚拟机linux下安装python3步骤
主要介绍了Python实现初始化不同的变量类型为空值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
python-simple-vm, 在 python 中,实现了一个简单的虚拟机 这是博客"在 python 中制作简单的VM解释器"的代码,你可以在 https://csl.name/post/vm/ 找到它。由 Stigen Larsen制作的,来自 R/python的人员的一些改进...
Pixie是具有7个寄存器,16个操作码和128 KB存储器的16位字寻址寄存器VM