import subprocess from threading import Thread import sys from time import time, sleep def thread_proc(id, path, n, on_exit, state): p = subprocess.Popen(["python.exe", path, n], stdout = subprocess.PIPE, stderr = subprocess.STDOUT, universal_newlines=True) for l in p.stdout: print(id, ": Child output:", l, end='') p.communicate() print(id, ": Child exited") on_exit(state) def on_0_exit(state): state["process_0_exit_time"] = time() def on_1_exit(state): if "process_0_exit_time" in state and \ time() - state["process_0_exit_time"] > 2: print("CORRECT: Thread 0 returned immediately after the child process 0 exited") else: print("ERROR: Thread 0 returned after two child processes exited") def test_main(): state = dict() thread0 = Thread(target=thread_proc, args=(0, sys.argv[0], "5", on_0_exit, state)) thread1 = Thread(target=thread_proc, args=(1, sys.argv[0], "10", on_1_exit, state)) thread0.start() # uncomment the following line to get expected result # sleep(1) thread1.start() thread0.join() thread1.join() def unbuffered_print(*args, **kwargs): print(*args, **kwargs) sys.stdout.flush() def test_child(): unbuffered_print("Child started") unbuffered_print("Waiting for", sys.argv[1], "seconds") sleep(int(sys.argv[1])) unbuffered_print("Child exiting") if __name__ == "__main__": if len(sys.argv) == 1: test_main() else: test_child()