I'm struggling with some processes I started with Popen and which start subprocesses. When I start these processes manually in a terminal every process terminates as expected if I send CTRL+C. But running inside a python program using subprocess.Popen any attempt to terminate the process only gets rid of the parent but not of its children.
I tried .terminate() ..kill() as well as ..send_signal() with signal.SIGBREAK, signal.SIGTERM, but in every case I just terminate the parent process.
With this parent process I can reproduce the misbehavior:
#!/usr/bin/python
import time
import sys
import os
import subprocess
import signal
if __name__ == "__main__":
  print os.getpid(), "MAIN: start a process.."
  p = subprocess.Popen([sys.executable, 'process_to_shutdown.py'])
  print os.getpid(), "MAIN: started process", p.pid
  time.sleep(2)
  print os.getpid(), "MAIN: kill the process"
  # these just terminate the parent:
  #p.terminate()
  #p.kill()
  #os.kill(p.pid, signal.SIGINT) 
  #os.kill(p.pid, signal.SIGTERM)
  os.kill(p.pid, signal.SIGABRT)
  p.wait()
  print os.getpid(), "MAIN: job done - ciao"
The real life child process is manage.py from Django which spawns a few subprocesses and waits for CRTL-C. But the following example seems to work, too:
#!/usr/bin/python
import time
import sys
import os
import subprocess
if __name__ == "__main__":
    timeout = int(sys.argv[1]) if len(sys.argv) >= 2 else 0
    if timeout == 0:
        p = subprocess.Popen([sys.executable, '-u', __file__, '13'])
        print os.getpid(), "just waiting..."
        p.wait()
    else:
        for i in range(timeout):
            time.sleep(1)
            print os.getpid(), i, "alive!"
            sys.stdout.flush()
    print os.getpid(), "ciao"
So my question in short: how do I kill the process in the first example and get rid of the child processes as well? On windows os.kill(p.pid, signal.CTRL_C_EVENT) seems to work in some cases, but what's the right way to do it? And how does a Terminal do it?
 
     
    