代码之家  ›  专栏  ›  技术社区  ›  conartist6

关闭这组流程的最佳方法是什么?

  •  1
  • conartist6  · 技术社区  · 15 年前

    我有以下一组进程,它们需要通过第一个列出的进程以编程方式关闭,这是我正在编码的C程序。

    PID   PGRP  SESN  PPID USER     TTY  CMD 
    6553  6553  6553     1 root     ?        ./startserv
    6554  6553  6553  6553 root     ?        expect -- /usr/bin/unbuffer ./srcds_run...
    6555  6555  6555  6554 root     pts/1    /bin/sh ./srcds_run -autoupdate -game c...
    6565  6555  6555  6555 root     pts/1    ./srcds_linux -autoupdate -game cstrike...
    

    在这种情况下,我通常用手杀死6553 6555。显然,我知道自己的PID,但编写类似于“kill my pid+2”的代码似乎有点傻(尽管这似乎[几乎]总是有效的)。帮助?

    5 回复  |  直到 15 年前
        1
  •  1
  •   Ana Betts    15 年前

    这些答案都不是很正确-最简单的处理方法是将进程放入进程组(子进程继承父进程组,因此闭源二进制文件也应该是好的)通过 getpgrp/setpgrp 然后一下子杀了他们 killpg 这就保证了它们都能同时接收到信号,而不存在任何让子进程在正确的时间分叉以逃脱的竞争条件。

        2
  •  0
  •   Eli Bendersky    15 年前

    这听起来像是一个全面的坏设计。你为什么要那样?这对你来说更有意义吗? startserv 将其他进程作为子进程启动的过程,在哪种情况下杀死它们很简单?你想达到什么目的?

        3
  •  0
  •   nategoose    15 年前

    从kill(2)系统调用的手册页:

    如果pid为负但不是-1,则向进程组ID等于pid绝对值且进程有权发送信号的所有进程(未指定的系统进程集除外)发送sig。

    编辑

    (我要求在此澄清,但我需要评论区没有的空间和格式)

    所以pstree会打印:

    startserv --- expect --- /bin/sh --- srcds_linux
    

    分组方式如下:

    {startserv --- expect} --- {/bin/sh --- srcds_linux}
    

    以及来自 startserv 你想杀人 expect , /bin/sh srcds_linux 但是杀人 期待 不会导致 期待 杀死它的直系子女(更不用说那个孩子所领导的群体)。

    还有一些建议

    可能是杀戮的预期,还有一些信号 SIGKILL (9)如 SIGTERM 可能导致 期待 在结束自己之前为你杀掉它的孩子(也许是群体),但你可能已经尝试过了。

    你可以试试看 /proc/*/stat 构建流程树,并找到 期待 进程(您已经知道它的PID),然后杀死它和它的所有子进程。这并不完美,因为它不是原子的(/bin/sh可以派生出更多的子级或其他内容),但是如果您还想尝试捕获它,可以发送此子树中的所有进程。 SIGSTOP 意识到他们在 期待 子树来稳定那棵树。然后给他们一个更强大的杀戮 SIGCONT .

    实现这一目标的一个更自动的方法是 启动服务 创建要运行的psudoterminal 期待 (及其后代)打开然后关闭psudoterminal的控制端,并希望所有这些程序都能继续运行。 SIGHUP .

        4
  •  0
  •   conartist6    15 年前

    看起来最简单的方法就是使用bash。我可以简单地捕获ps-axo-pid,ppid的输出。我已经有了第一个进程用它的pid生成一个锁文件,所以bash脚本可以用父进程的pid的ppid查找第一个项目,并将其与父进程一起发送一个sigterm。

        5
  •  0
  •   conartist6    15 年前

    最后,我的解决方案是: 获取父进程从程序中派生的子进程的PID(预期进程)。 将该PID和第一个进程的PID一起写入锁文件。 编写一个bash脚本来查找哪些进程具有第二个进程的PID的父进程。 杀死第一个进程和bash脚本返回的进程ID。一切都完好无损。有可能最好将killpg命令与此方法结合使用,我将看一看。