如果有的话,CPython 中堆栈的用途是什么?
What is the stack used for in CPython, if anything?
据我了解:
- OS 内核(例如Linux)总是 allocates a stack 为每个系统级线程创建线程时。
- CPython 以使用 private heap for its objects, including presumably the call stack 作为 Python 子例程而闻名。
如果是,那么 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);
// ...
}
据我了解:
- OS 内核(例如Linux)总是 allocates a stack 为每个系统级线程创建线程时。
- CPython 以使用 private heap for its objects, including presumably the call stack 作为 Python 子例程而闻名。
如果是,那么 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);
// ...
}