2010-09-16 46 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

相關問題