2014-01-13 208 views
6

我一直有一個問題,我可以殺死產生節點的進程,但節點不會被殺死。有沒有人有任何建議我可以做到這一點?子進程殺死子進程但不是子進程的進程

我的一些最新的失敗嘗試做到這一點是:

node.terminate() 

node.send_signal(signal.SIGINT) 
下面

是代碼:

from subprocess import Popen 
import json 
import sys 
import os 
import signal 
import requests 

FNULL = open(os.devnull, 'w') 

json_data = open('nodes.json', 'r').read() 
data = json.loads(json_data) 

port = data['port'] 

# launch hub 
hub = Popen('java -jar selenium-server-standalone-2.37.0.jar -role hub -port %s' % port, stdout=FNULL, stderr=FNULL, shell=True) 

#launch nodes 
nodes = [] 
for node in data['nodes']: 
    options = '' 
    if node['name'] == 'CHROME': 
     options += '-Dwebdriver.chrome.driver=../grid/chromedriver ' 
    #options += ' -browser browserName='+node['name']+' maxInstances='+str(node['maxInstances']) 
    nodes.append(Popen('java -jar selenium-server-standalone-2.37.0.jar -role node -hub http://localhost:%i/grid/register %s' % (port, options), stdout=FNULL, stderr=FNULL, shell=True)) 

# wait for user input 
print "type 'q' and ENTER to close the grid:" 
while True: 
    line = sys.stdin.readline() 
    if line == 'q\n': 
     break 

# close nodes 
for node in nodes: 
    #node.terminate() 
    node.send_signal(signal.SIGINT) 

# close hub 
r = requests.get('http://localhost:'+str(port)+'/lifecycle-manager?action=shutdown') 

至於即時知道,我m基本上被迫使用shell = True,重定向工作 在t中處理孩子的stdout/stderr他父Python進程是不是一種選擇,因爲我無法在非等待的方式做它找到的功能(和孩子正在運行而父蟒蛇過程中必須做其他事情)

# close nodes 
for node in nodes: 
    node.send_signal(signal.SIGINT) 
    node.terminate()  

這似乎殺死除1個節點以外的所有進程。不總是一樣的

+0

嘗試添加:''node.wait()'' –

+0

@JamesMills添加node.wait()似乎阻止關機,可能是由於節點仍處於活動狀態(因此它只是在等待它們完成) – Calum

+0

如果你不設置'shell = True'會怎麼樣? – kojiro

回答

2

你可以嘗試使用os.killpg。該函數將信號發送給進程組,如果進程不改變進程組,它應該工作。

import os 
import signal 

os.killpg(os.getpgid(pid), signal.SIGINT) 

注意,這個過程將組如果要創建下外殼(bash中,zsh中,等)過程中發生變化,在這種情況下,更復雜的技術應該被使用。

+1

os.killpg(os.getpgid(pid),signal.SIGINT) – DanJ

+0

@DanJ謝謝,我編輯過我的回答 – maxbublis

+1

不幸的是,這也殺死了調用程序。您需要將「preexec_fn = os.setsid」添加到「Popen」。 –