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.
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:17 | admin | set | github: 56253 |
| 2011年07月05日 20:36:58 | vstinner | set | nosy:
+ vstinner messages: + msg139904 |
| 2011年05月12日 14:48:27 | python-dev | set | messages: + msg135841 |
| 2011年05月12日 05:23:31 | gregory.p.smith | set | status: open -> closed resolution: accepted messages: + msg135816 |
| 2011年05月12日 05:20:58 | python-dev | set | messages: + msg135815 |
| 2011年05月12日 04:42:23 | python-dev | set | nosy:
+ python-dev messages: + msg135814 |
| 2011年05月11日 20:12:57 | gregory.p.smith | set | assignee: gregory.p.smith |
| 2011年05月11日 16:44:29 | neologix | set | status: closed -> open files: + subprocess_zombie.diff messages: + msg135783 components: + Library (Lib) keywords: + patch resolution: rejected -> (no value) |
| 2011年05月11日 08:57:51 | gregory.p.smith | set | messages: + msg135765 |
| 2011年05月10日 16:08:26 | neologix | set | messages: + msg135715 |
| 2011年05月10日 09:11:45 | pitrou | set | status: pending -> closed resolution: rejected messages: + msg135690 |
| 2011年05月10日 02:28:20 | brian.curtin | set | status: open -> pending messages: + msg135675 |
| 2011年05月09日 22:00:40 | pitrou | set | messages: + msg135658 |
| 2011年05月09日 21:11:27 | brian.curtin | set | messages: + msg135652 |
| 2011年05月09日 21:05:14 | pitrou | set | messages: + msg135649 |
| 2011年05月09日 21:02:25 | brian.curtin | set | messages: + msg135648 |
| 2011年05月09日 20:42:15 | pitrou | set | messages: + msg135642 |
| 2011年05月09日 20:41:02 | brian.curtin | set | messages: + msg135641 |
| 2011年05月09日 19:24:14 | pitrou | create | |