--- Lib/subprocess.py 2004-11-07 15:30:34.000000000 +0100 +++ /home/mattias/bugs/subprocess.py 2005-04-22 18:03:48.000000000 +0200 @@ -50,7 +50,7 @@ stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, - startupinfo=None, creationflags=0): + startupinfo=None, creationflags=0, autowait=True): Arguments are: @@ -122,6 +122,16 @@ appearance of the main window and priority for the new process. (Windows only) +If autowait is true or omitted, then the new process will be waited +for automatically if it has terminated when another Popen instance is +created. This is done to keep too many zombie processes from lingering +in the system. If false, then the user is responsible for waiting for +the process (retrieving its exit status from the operating system), +either using the poll(), wait() or communicate() methods or the +os.wait()/os.waitpid() functions. In order to use os.wait() or +os.waitpid() with the process ID of the created process, autowait +should be set to false. + This module also defines two shortcut functions: @@ -237,7 +247,7 @@ --------------------- sts = os.system("mycmd" + " myarg") ==> -p = Popen("mycmd" + " myarg", shell=True) +p = Popen("mycmd" + " myarg", shell=True, autowait=False) sts = os.waitpid(p.pid, 0) Note: @@ -245,7 +255,7 @@ * Calling the program through the shell is usually not required. * It's easier to look at the returncode attribute than the - exitstatus. + exit status. A more real-world example would look like this: @@ -289,6 +299,11 @@ Popen(["/bin/mycmd", "myarg"], env={"PATH": "/usr/bin"}) +Note: In order to use os.wait() or os.waitpid() with the process ID +of the created Popen object, the autowait parameter should be set +to False. + + Replacing os.popen* ------------------- pipe = os.popen(cmd, mode='r', bufsize) @@ -407,10 +422,10 @@ False = 0 True = 1 -_active = [] +_active = {} # set of instances to auto-wait for def _cleanup(): - for inst in _active[:]: + for inst in _active.keys(): inst.poll() PIPE = -1 @@ -500,7 +515,7 @@ stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, - startupinfo=None, creationflags=0): + startupinfo=None, creationflags=0, autowait=True): """Create new Popen instance.""" _cleanup() @@ -566,7 +581,8 @@ else: self.stderr = os.fdopen(errread, 'rb', bufsize) - _active.append(self) + if autowait: + _active[self] = 1 def _translate_newlines(self, data): @@ -748,7 +764,7 @@ if self.returncode == None: if WaitForSingleObject(self._handle, 0) == WAIT_OBJECT_0: self.returncode = GetExitCodeProcess(self._handle) - _active.remove(self) + del _active[self] return self.returncode @@ -758,7 +774,7 @@ if self.returncode == None: obj = WaitForSingleObject(self._handle, INFINITE) self.returncode = GetExitCodeProcess(self._handle) - _active.remove(self) + del _active[self] return self.returncode @@ -995,7 +1011,7 @@ # Should never happen raise RuntimeError("Unknown child exit status!") - _active.remove(self) + del _active[self] def poll(self):