Repository navigation
fix(tools): 取消 exec 时终止整棵进程树(Windows) - #152
Merged
Merged
Conversation
_terminate_process 的 Windows 分支只 terminate()/kill() 了 cmd.exe,而 start_new_session 是 POSIX 专有参数,Windows 下不生效,sleep / npm 这类 子进程会存活并继续持有继承来的 stdout/stderr 管道。等待输出的一方读不到 EOF,取消后调用要挂到超时才返回,子进程则在后台继续跑。 改为 Windows 上走 taskkill /F /T /PID 递归结束进程树,失败再退回单进程 kill。对应测试 test_exec_terminates_process_on_cancel 在 Windows CI 上 正是超时失败。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
变更说明
合并 #151 后,main 上第一次 CI 在 Windows 只挂了一条:
日志里同时出现
Terminate orphan process: pid (2036) (sleep),说明被取消的命令进程活到了 job 收尾。根因
_terminate_process()的 Windows 分支只对 shell 本体terminate()/kill():start_new_session=True(创建子进程时传入)是 POSIX 专有参数,Windows 直接忽略,所以没有「进程组」可用;cmd.exe /c sleep 30被结束后,sleep.exe成为孤儿,继续持有继承来的 stdout/stderr 管道;_collect_process_output()读不到 EOF,取消后的调用一直挂着,直到外层超时才返回。对桌面版的实际影响:Windows 上点停止,命令其实还在跑,工具调用卡到超时。
修改
_terminate_process()在 Windows 上改走_kill_process_tree_windows():taskkill /F /T /PID <pid>递归结束整棵进程树,失败再退回单进程kill()。POSIX 分支(SIGTERM → SIGKILL 按进程组)保持不变。验证
pytest tests708 passed(Python 3.11 与 3.12 各一遍)