""" Test for Python issue 2320 ("Race condition in subprocess using stdin") Note that the name of the issue is over-specific. As demonstrated below, one need not use stdin to reproduce the problem. To run: A) Create my_subprocess.py by copying the default subprocess.py and applying the patch below (exists only to encourage the race condition. If simply adding a sleep reliably breaks it, then there is a race condition) B) Execute python subprocess_race_condition.py C) Observe that the thread that launches the "immediately terminate" child never returns from subprocess.Popen.__init__. That is a bug. D) Set "do_close_fds" to True and observe that the parent does indeed terminate, leaving the child running in the background. Tested on: Debian Lenny/Sid with Python 2.5.2-2 Linux creechb-linux 2.6.25-2-686 #1 SMP Fri Jul 18 17:46:56 UTC 2008 i686 GNU/Linux --- /usr/lib/python2.5/subprocess.py 2008-08-08 06:34:33.000000000 -0400 +++ my_subprocess.py 2008-10-24 17:43:00.000000000 -0400 @@ -1059,6 +1059,8 @@ # The first char specifies the exception type: 0 means # OSError, 1 means some other error. errpipe_read, errpipe_write = os.pipe() + import time + time.sleep(5) self._set_cloexec_flag(errpipe_write) gc_was_enabled = gc.isenabled() """ import sys, os, threading, time do_close_fds=False def launchChild(mode): print 'Launching child in mode ' + mode s = my_subprocess.Popen( 'python subprocess_race_condition.py ' + mode, shell=True, close_fds=do_close_fds) print 'Done launching child in mode ' + mode if len(sys.argv) == 1: import my_subprocess threading.Thread(target=lambda: launchChild('never_terminate')).start() time.sleep(1) threading.Thread(target=lambda: launchChild('immediately_terminate')).start() else: if sys.argv[1] == 'never_terminate': while 1: time.sleep(1) print 'hello from never-ending child process' else: time.sleep(1) print 'hello from immediately-ending child process'