import os import sys import time import signal import ctypes import subprocess kernel32 = ctypes.WinDLL('kernel32') def handler(*args): print('Process %04d: received CTRL+C' % os.getpid()) sys.exit(0) signal.signal(signal.SIGINT, handler) def parent(): p = subprocess.Popen([sys.executable, __file__, 'child'], creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) print('Process %04d: created process %04d' % (os.getpid(), p.pid)) pychild = kernel32.CreateEventW(None, 0, 0, 'pychild') # wait for the child and grandchild to be ready kernel32.WaitForSingleObject(pychild, 4000) # send CTRL+C to them both p.send_signal(signal.CTRL_C_EVENT) try: p.wait(4) except subprocess.TimeoutExpired: p.kill() def child(): # enable CTRL+C kernel32.SetConsoleCtrlHandler(None, 0) p = subprocess.Popen([sys.executable, __file__, 'grandchild']) print('Process %04d: created process %04d' % (os.getpid(), p.pid)) pychild = kernel32.CreateEventW(None, 0, 0, 'pychild') pygrandchild = kernel32.CreateEventW(None, 0, 0, 'pygrandchild') kernel32.WaitForSingleObject(pygrandchild, 3000) kernel32.SetEvent(pychild) time.sleep(3) def grandchild(): pygrandchild = kernel32.CreateEventW(None, 0, 0, 'pygrandchild') kernel32.SetEvent(pygrandchild) time.sleep(3) if __name__ == '__main__': if len(sys.argv) < 2: parent() elif sys.argv[1] == 'child': child() elif sys.argv[1] == 'grandchild': grandchild()