【问题标题】:How to avoid zombie processes when killing rake tasks?杀死rake任务时如何避免僵尸进程?
【发布时间】:2013-01-29 00:03:00
【问题描述】:

我有一个连续调用几个 rake 任务的 bash 脚本。该脚本由持续集成服务器调用。问题是如果集成服务器终止任务(通过向脚本发送 SIGTERM),我无法让整个进程树被终止。例如,如果 Rake 正在使用 Parallel 功能运行一组 rspec 测试,则可以终止脚本和顶级 rake 命令,但不可避免地会有一些线程继续运行。

到目前为止,我已经尝试了许多在 bash 脚本中使用“trap”命令的不同方法。我尝试使用 pstree 查找所有子进程,使用“kill -9 0”杀死当前进程组等。但是,如果脚本在 rake 任务运行时被杀死,它似乎绕过了陷阱。据我所知,Rake 或者 Ruby 的线程库对进程组做了一些奇怪的事情,或者可能会干扰陷阱。

如果脚本不在 rake 任务的中间,它将正确捕获 SIGTERM,回显“Received SIGTERM”,然后杀死所有后代。

Rake 如何干扰父进程(bash 脚本)中的陷阱语句?

【问题讨论】:

    标签: ruby bash rake kill zombie-process


    【解决方案1】:

    Bash 假设整个进程组都收到了信号,所以它会等待当前执行的命令完成来确定要做什么(more info)。在命令完成之前,陷阱不会运行。

    如果您不想等待命令完成,可以改为使用

    trap 'kill $!' TERM
    job &
    wait $!
    

    wait 将在 shell 收到 SIGTERM 时立即退出,从而导致您的陷阱立即运行。

    【讨论】:

    • 我能够以有限的方式使用它。我只能在顶级脚本中执行此操作(直接接收 SIGTERM)。此外,我仍然无法处理进程 id 组来杀死所有后代(我要么什么都不杀死,要么杀死所有东西,包括持续集成服务器本身),所以我不得不在陷阱中做一个丑陋的“killall -9 rake”。但是,它解决了能够可靠地执行任何陷阱语句的核心问题,所以我接受它..
    • 当您使用& 运行命令时,它们应该成为一个可以使用kill -TERM -$! 杀死的新进程组
    猜你喜欢
    • 2013-06-01
    • 2011-02-15
    • 2014-06-19
    • 2015-04-12
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2011-09-26
    • 2017-08-23
    相关资源
    最近更新 更多