2010-09-16 49 views
1

我有以下一组进程,需要通过第一个列出的进程以编程方式关闭,这是我正在编写的一个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,但似乎有点傻编写类似“杀了我的PID + 2”(尽管它似乎这将[几乎]始终有效。帮助?

+0

杀死'expect'过程(6554以上)是否会杀死它的孩子(6555)? – bstpierre 2010-09-16 16:07:30

+0

您可以扩展'expect'的运行方式吗?完整的argv,带有关于文件类型的注释,以及关于发生的fork ... exec的任何特殊情况。 – nategoose 2010-09-16 20:17:57

回答

0

最后我的解决方案是: 获得父程序从父程序中分配的子进程的pid(期望进程)。 将该pid与第一个进程的pid一起写入锁定文件。 编写一个bash脚本,查找哪些进程具有父进程的第二个进程的pid。 杀死bash脚本返回的第一个进程和进程ID。一切都彻底结束。有可能最好在这个方法中使用killpg命令,我会看看这个。

0

这听起来像是一个全面的不良设计,为什么你需要这样的设计?对于你的startserv进程来说,启动其他的子进程会更有意义,其中这种情况下查杀他们很简单吗?你想做什么?

+0

它是这样的原因是因为我只写了最上面的过程。其他三个人都有自己的想法,基本上是封闭的。 – conartist6 2010-09-16 19:47:02

0

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

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

编辑

(我要求澄清一下,但我需要空间和格式所不具备在评论区)

所以pstree将打印:

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

并且将组分组为:

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

而且从startserv你想杀expect,/bin/shsrcds_linux,但是杀expect不会导致expect杀死它的直接孩子(更不用说那个孩子是他的头)。

一些更多的建议

这可能是因为一些信号杀害想到除了SIGKILL(9)如SIGTERM可能导致expect终止本身之前杀死其子(也许集团)你,但你可能有已经试过了。你可以试着通过/proc/*/stat来建立一个进程树,并找到你的expect进程(你已经知道它的pid),然后杀掉它和它的所有子进程。这不是完美的,因为它不是原子的(/ bin/sh可以分出更多的子元素或其他东西),但是如果你想尝试去捕获它,你可以发送子树SIGSTOP中的所有进程,在expect子树下稳定那棵树。然后发送给他们一个更强的杀可能接着是SIGCONT

更自动化的方式来完成,这将是有startserv创建一个psudoterminal运行expect(及其后代),然后关闭psudoterminal的控制端,并希望所有这些方案的死在SIGHUP

+0

但是列出的过程没有相同的PGRP。 'expect'创建一个新组。 – bstpierre 2010-09-16 16:06:05

+0

pstree给我 | -startserv ---期望--- srcds_run --- srcds_linux --- 3 * [{srcds_linux}] 我真的不需要担心奇怪的情况,发送一个sigterm到6555(in本案)将终止所有6555(即6556)孩子的过程。杀戮(术语)6553摆脱了553和554.那么,假设这个过程的分组总是相似的,并且假设将两个加起来很愚蠢,那么获得第三个列出的过程的最佳方式是什么? – conartist6 2010-09-16 19:41:29

0

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

1

这些答案都不是非常正确 - 处理这个问题的最简单方法是通过​​将进程放入进程组(子进程继承父进程组,因此您的闭源进程应该也是好的)然后通过killpg一举将它们全部杀死,这可以保证所有人都能在同一时间收到信号,没有任何竞争条件可以让孩子在正确的时间分岔逃跑。

+2

但期望创造一个父母没有直接意识到的新的pg。 – bstpierre 2010-09-16 21:01:46

相关问题