为什么 VS Code 的集成 Python 调试会启动多个调试线程?

And*_* L. 5 python debugging multithreading visual-studio-code vscode-debugger

** 更新 **

相关讨论中我得到了以下答案:

另外,在代码中需要仔细检查的是主入口点是否受到__name__=='__main__'检查保护:

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

根据结构,multiprocessing.freeze_support()如果您需要多处理支持,您可能还需要:

IE:

if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()
Run Code Online (Sandbox Code Playgroud)

(如果您没有该结构,它可以解释为什么多处理多次执行您的主入口点代码)。

然而,我既没有实现上述第一个选项,也没有实现第二个选项,而且,我执行的任何脚本都可能发生这种突然的多线程行为。似乎旧的/以前的调试会话并没有在幕后真正终止,因为在一个会话中没有多线程,然后在调试时启动多会话。正常执行代码时也会发生这种情况,代码退出时出现错误,然后我(再次)进入调试会话。

我不知道如何实现它,但我应该把

if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()
Run Code Online (Sandbox Code Playgroud)

在我作为主脚本执行的所有 python 脚本的开头,即我的入口点或顶级脚本?

** 原始问题 **

从所附的屏幕截图中可以看出,在通过按下执行标准调试过程(之前定义了一些断点)时,偶尔会发生以下情况:F5VS Code

VS Code 中的 Python 调试

这会导致大量额外的计算时间、滞后和冗余的控制台输出,因为相同的代码连续执行多次。

奇怪的是,这种行为似乎是随机发生的。只有有时我才能得出结论,我之前尝试启动调试会话,该会话在代码中的某个时刻被 中断,但对我来说,为什么要重新启动所有这些以前失败的调试会话以及新的调试会话,Uncaught Exception这似乎不合逻辑VS Code按下时为一F5

Shift+F5当通过或 红色方形按钮中断调试程序时,有时会在 - 窗口右下角出现Stop该消息;特别是当问题发生时,显示.timeout after 1000 msVS Codecall stack

launch.json定义集成终端调试的my - 文件的相关部分是:

{
    // !!THIS CONFIG-FILE IS USED FOR DEBUGGING!!
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python: Current File (Integrated Terminal)",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            // VS Code Integrated Terminal. If redirectOutput is set to True, output is also displayed in the debug console.
            "console": "integratedTerminal",
            // Make sure that code output is also being displayed in the debug console.
            "redirectOutput": true,
            // When omitted or set to true (the default), restricts debugging to user-written code only. Set to false to also enable debugging of standard library functions.
            "justMyCode": false
        },
...
Run Code Online (Sandbox Code Playgroud)

至于- 文件,除了 generic option 之外,settings.json我还没有实现任何有关python 调试"debug.allowBreakpointsEverywhere": true的选项。

我想了解为什么这种不受欢迎的调试行为首先会出现,并最终能够防止它发生。


PS:尝试在VS Code 的官方 GitHub上获取答案:

我已在 VS Code GitHub-page 上提交了一个问题,但建议我在 StackOverflow 上提问,因为

“VS Code 仅显示 Python 调试器所请求的内容。”

And*_* L. 3

我在这个线程中找到了解决方案。

把它们加起来,

建议在主脚本的末尾(即执行开始的起始入口脚本)实现以下内容:

if __name__ == '__main__':
    multiprocessing.freeze_support()
    main()
Run Code Online (Sandbox Code Playgroud)

该行在multiprocessing.freeze_support()UNIX 系统上不会造成任何损害/没有任何作用,并且可以在 Windows 上运行。如果读者想了解有关此功能的更深入的知识,请参阅上面提到的 GitHub-discussion 的文档这一部分。

但最重要的部分(请参阅此处

main()从“警卫之下”打来的电话

其中“守卫”代表if __name__ == '__main__':

此外,正如这里所解释的那样,

它通常应该位于脚本的末尾,并且函数中尚未包含的所有顶级代码都应该位于main(). 原因是您的脚本将作为多处理生成的每个子进程中的模块导入,因此任何顶级代码都将在没有防护的情况下运行多次。但只有直接作为脚本启动的实例才会具有__name__ == "__main__".