A subprocess kills child processes, but not the processes that the child spawns.

I have a problem where I can kill processes that spawn nodes, but the nodes are not killed. Can anyone suggest how I can do this?

Some of my last unsuccessful attempts to accomplish this:

node.terminate() 

and

 node.send_signal(signal.SIGINT) 

Below is the code:

 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') 

As far as I know, I am basically forced to use shell = True to get redirects to work Handling the child stdout / stderr in the parent python process is not an option, since I could not find the functionality for this in standby mode (and the parent python process should perform other actions while the child is running)

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

this seems to kill all processes except 1 of the nodes. Not always the same

+6
source share
1 answer

You can try using os.killpg . This function sends a signal to a process group, it should work if your processes do not change the process group.

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

Please note that this group of processes will be changed if you create a process under the shell (bash, zsh, etc.), in this case you should use a more complex method.

+2
source

All Articles