homepage

This issue tracker has been migrated to GitHub , and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: subprocess.Popen.__exit__ doesn't wait for process end
Type: behavior Stage:
Components: Library (Lib) Versions: Python 3.2, Python 3.3
process
Status: closed Resolution: accepted
Dependencies: Superseder:
Assigned To: gregory.p.smith Nosy List: brian.curtin, gregory.p.smith, neologix, pitrou, python-dev, vstinner
Priority: normal Keywords: patch

Created on 2011年05月09日 19:24 by pitrou, last changed 2022年04月11日 14:57 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
subprocess_zombie.diff neologix, 2011年05月11日 16:44 review
Messages (17)
msg135635 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011年05月09日 19:24
I find it a bit strange that Popen.__exit__ closes all standard file descriptors leading to the child process, but doesn't wait for process end afterwards.
(context management support was added in issue10554)
msg135641 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2011年05月09日 20:41
Seems like it would be enough to add a wait() at the end?
diff -r 9e473917cbfb Lib/subprocess.py
--- a/Lib/subprocess.py Mon May 09 21:17:02 2011 +0200
+++ b/Lib/subprocess.py Mon May 09 15:30:02 2011 -0500
@@ -796,6 +796,7 @@
 self.stderr.close()
 if self.stdin:
 self.stdin.close()
+ self.wait()
 def __del__(self, _maxsize=sys.maxsize, _active=_active):
 if not self._child_created:
msg135642 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011年05月09日 20:42
> Seems like it would be enough to add a wait() at the end?
Probably, perhaps with a try/finally?
I'm not entirely sure this is a good idea, by the way. May there be some
drawbacks?
msg135648 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2011年05月09日 21:02
Actually, I don't think the wait() is a good idea. If you want to block and infinitely wait on the process to close, you should do so explicitly.
It's probably better that we try to use terminate() or kill() and raise if that fails.
msg135649 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011年05月09日 21:05
> Actually, I don't think the wait() is a good idea. If you want to
> block and infinitely wait on the process to close, you should do so
> explicitly.
Ok.
> It's probably better that we try to use terminate() or kill() and raise if that fails.
Uh, I think it's worse. Using a context manager shouldn't do something
potentially destructive like killing a process.
msg135652 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2011年05月09日 21:11
Hm, yeah, not sure what I was thinking there.
I'm thinking there's not a lot we can do here, but also not a lot that we should do here. We don't want to wait, and we don't want to close, so maybe we should just document that the usage should be limited only to expecting the open handles to be closed?
msg135658 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011年05月09日 22:00
> I'm thinking there's not a lot we can do here, but also not a lot that
> we should do here. We don't want to wait, and we don't want to close,
> so maybe we should just document that the usage should be limited only
> to expecting the open handles to be closed?
Sounds good indeed :)
msg135675 - (view) Author: Brian Curtin (brian.curtin) * (Python committer) Date: 2011年05月10日 02:28
Looks like we already mention that.
"""
Popen objects are supported as context managers via the with statement, closing any open file descriptors on exit.
"""
Antoine, do you think this should be more strongly worded?
msg135690 - (view) Author: Antoine Pitrou (pitrou) * (Python committer) Date: 2011年05月10日 09:11
Well, no, looks ok for me then :)
msg135715 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2011年05月10日 16:08
There's just one thing I'm concerned with.
People using context managers tend to expect the __exit__ method to
perform cleanup actions and release corresponding resources if
necessary, for example closing the underlying file or socket.
So my guess is that most people won't explicitly wait for the process
termination. You can already find such examples inside
test_subprocess.py, Lib/ctypes/util.py (to parse ldconfig's output),
and even in subprocess' documentation:
"""
with Popen(["ifconfig"], stdout=PIPE) as proc:
 log.write(proc.stdout.read())
"""
The problem is that until a child process is wait()ed on or its parent
process terminates (so that the child gets re-parented to init), the
child remains a zombie/defunct process. So if you have long-running
process spawning many subprocesses, you could end up having many
zombie processes, potentially filling up your process table at some
point. And this really sucks.
So I think it could be worth mentioning this somewhere in the
documentation (I mean, if we can find find such leaks inside CPython
code base, then it's definitely something that should be documented).
msg135765 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2011年05月11日 08:57
I didn't initially like the idea of __exit__ blocking on another
process... but the zombie issue is real does make me think we should
reconsider this and have it wait().
It is a backwards incompatible change if anyone has started using the
Popen context manager to launch a long running subprocess that they
did not want to wait for. That should be exceedingly rare.
I say change the behavior to wait() in 3.3, 3.2.1 and 2.7.2. Keep the
note in the documentation and turn it into something that stands out
better like a note or a warning suggesting that people always call
wait() after the Popen context manager exits if they need to be
compatible with 2.7.1 or earlier.
msg135783 - (view) Author: Charles-François Natali (neologix) * (Python committer) Date: 2011年05月11日 16:44
I'm re-opening this issue, since Gregory agrees to change the current behaviour.
Patch attached (along with test and documentation update).
msg135814 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年05月12日 04:42
New changeset 7a3f3ad83676 by Gregory P. Smith in branch 'default':
- Issue #12044: Fixed subprocess.Popen when used as a context manager to
http://hg.python.org/cpython/rev/7a3f3ad83676 
msg135815 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年05月12日 05:20
New changeset b00a64a5cb93 by Gregory P. Smith in branch '3.2':
merge - 7a3f3ad83676 Fixes Issue #12044.
http://hg.python.org/cpython/rev/b00a64a5cb93 
msg135816 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2011年05月12日 05:23
did my commits in the reverse order (default before 3.2), oops. this is fixed. this wasn't ever in 2.7 so no need for the documentation note. i'm not worried about adding a note about 3.2.0 vs 3.2.1 beyond the mention in Misc/NEWS as this was new in 3.2.0 and fixing this behavior is a pretty clear bug fix.
msg135841 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2011年05月12日 14:48
New changeset 361f87c8f36a by Łukasz Langa in branch 'default':
Cleaned up a backward merge after fixes issue #12044.
http://hg.python.org/cpython/rev/361f87c8f36a 
msg139904 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2011年07月05日 20:36
See also issue #12494: "subprocess: check_output() doesn't close pipes on error".
History
Date User Action Args
2022年04月11日 14:57:17adminsetgithub: 56253
2011年07月05日 20:36:58vstinnersetnosy: + vstinner
messages: + msg139904
2011年05月12日 14:48:27python-devsetmessages: + msg135841
2011年05月12日 05:23:31gregory.p.smithsetstatus: open -> closed
resolution: accepted
messages: + msg135816
2011年05月12日 05:20:58python-devsetmessages: + msg135815
2011年05月12日 04:42:23python-devsetnosy: + python-dev
messages: + msg135814
2011年05月11日 20:12:57gregory.p.smithsetassignee: gregory.p.smith
2011年05月11日 16:44:29neologixsetstatus: closed -> open
files: + subprocess_zombie.diff
messages: + msg135783

components: + Library (Lib)
keywords: + patch
resolution: rejected -> (no value)
2011年05月11日 08:57:51gregory.p.smithsetmessages: + msg135765
2011年05月10日 16:08:26neologixsetmessages: + msg135715
2011年05月10日 09:11:45pitrousetstatus: pending -> closed
resolution: rejected
messages: + msg135690
2011年05月10日 02:28:20brian.curtinsetstatus: open -> pending

messages: + msg135675
2011年05月09日 22:00:40pitrousetmessages: + msg135658
2011年05月09日 21:11:27brian.curtinsetmessages: + msg135652
2011年05月09日 21:05:14pitrousetmessages: + msg135649
2011年05月09日 21:02:25brian.curtinsetmessages: + msg135648
2011年05月09日 20:42:15pitrousetmessages: + msg135642
2011年05月09日 20:41:02brian.curtinsetmessages: + msg135641
2011年05月09日 19:24:14pitroucreate

AltStyle によって変換されたページ (->オリジナル) /