You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Windows Docker下GitLab Runner运行Python3时os.kill执行失败问题咨询

问题根因

该报错的核心原因是GitLab Runner的docker-windows执行器默认不会为作业容器分配伪终端(TTY),而Windows系统的CTRL_BREAK_EVENT信号投递逻辑强依赖控制台会话存在:

  • 你手动执行docker run -it命令时,-i(交互式)和-t(分配伪终端)参数会为容器绑定一个可用的控制台会话,msys2 Python调用os.kill发送CTRL_BREAK_EVENT时,底层Win32 APIGenerateConsoleCtrlEvent可以正常找到目标进程组完成信号投递,所以脚本运行正常。
  • GitLab Runner默认启动作业容器时不会携带-t参数,容器内所有进程都运行在无关联控制台的无头环境下,此时调用GenerateConsoleCtrlEvent会因为没有可用的控制台触发事件直接返回错误,最终被Python封装抛出WinError 1 Incorrect function异常。

你可以通过以下命令手动复现GitLab Runner环境的报错,验证根因:

docker run --rm -v C:\TMP:C:\build test_image python3 C:\build\silly.py
解决方案

方案一:为docker-windows执行器开启TTY配置

修改GitLab Runner的config.toml配置文件,在对应docker-windows执行器的配置段添加tty = true参数即可,示例配置如下:

[[runners]]
  name = "Windows Docker 执行器"
  executor = "docker-windows"
  shell = "powershell"
  [runners.docker]
    tty = true
    image = "你的自定义镜像名称"
    isolation = "process"
    # 其余原有配置保持不变

配置修改完成后重启GitLab Runner服务,作业容器就会分配伪终端,脚本可以正常运行。

方案二:替换信号发送逻辑(无需修改Runner配置)

如果无法修改Runner配置,可以放弃使用CTRL_BREAK_EVENT,改用Windows原生的taskkill命令完成进程树终止,替换proc.send_signal( signal.CTRL_BREAK_EVENT )代码为如下内容即可:

subprocess.run(['taskkill', '/F', '/T', '/PID', str(proc.pid)], capture_output=True, check=True)

该命令不需要控制台会话支持,在无头环境下也能正常终止目标进程及其所有子进程。

内容的提问来源于stack exchange,提问作者susundberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:09:01