【发布时间】:2020-09-26 20:48:36
【问题描述】:
据我所知:
- 创建线程时每个系统级线程的操作系统内核(例如 Linux)总是 allocates a stack。
- CPython 以其对象使用 private heap 而闻名,其中可能包括用于 Python 子例程的 call stack。
如果有,CPython 中使用的堆栈是什么?
【问题讨论】:
标签: memory-management kernel cpython
据我所知:
如果有,CPython 中使用的堆栈是什么?
【问题讨论】:
标签: memory-management kernel cpython
CPython 是一个普通的C 程序。运行 Python 脚本/模块/REPL/任何东西没有什么神奇之处:必须在循环中读取、解析、解释每段代码,直到完成。每个 Python 表达式和语句背后都有一大堆处理器指令。
每个“简单”的顶级事物(字节码的解析和生成、GIL 管理、属性查找、控制台 I/O 等)在底层都非常复杂。如果由函数组成,调用其他函数,调用其他函数......这意味着涉及堆栈。说真的,check it你自己:一些源文件跨越几千行代码。
到达解释器的主循环本身就是一次冒险。以下是从代码库各处拼凑而成的要点:
#ifdef MS_WINDOWS
int wmain(int argc, wchar_t **argv)
{
return Py_Main(argc, argv);
}
#else
// standard C entry point
#endif
int Py_Main(int argc, wchar_t **argv)
{
_PyArgv args = /* ... */;
return pymain_main(&args);
}
static int pymain_main(_PyArgv *args)
{
// ... calling some initialization routines and checking for errors ...
return Py_RunMain();
}
int Py_RunMain(void)
{
int exitcode = 0;
pymain_run_python(&exitcode);
// ... clean-up ...
return exitcode;
}
static void pymain_run_python(int *exitcode)
{
// ... initializing interpreter state and startup config ...
// ... determining main import path ...
if (config->run_command) {
*exitcode = pymain_run_command(config->run_command, &cf);
}
else if (config->run_module) {
*exitcode = pymain_run_module(config->run_module, 1);
}
else if (main_importer_path != NULL) {
*exitcode = pymain_run_module(L"__main__", 0);
}
else if (config->run_filename != NULL) {
*exitcode = pymain_run_file(config, &cf);
}
else {
*exitcode = pymain_run_stdin(config, &cf);
}
// ... clean-up
}
int PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit, PyCompilerFlags *flags)
{
// ... even more routing ...
int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
// ...
}
int PyRun_InteractiveLoopFlags(FILE *fp, const char *filename_str, PyCompilerFlags *flags)
{
// ... more initializing ...
do {
ret = PyRun_InteractiveOneObjectEx(fp, filename, flags);
// ... error handling ...
} while (ret != E_EOF);
// ...
}
【讨论】: