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 2019年01月17日 04:29 by Kirill Kolyshkin, last changed 2022年04月11日 14:59 by admin. This issue is now closed.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 11584 | closed | Kirill Kolyshkin, 2019年01月17日 04:29 | |
| Messages (3) | |||
|---|---|---|---|
| msg333819 - (view) | Author: Kirill Kolyshkin (Kirill Kolyshkin) * | Date: 2019年01月17日 04:29 | |
In case close_fds=True is passed to subprocess.Popen()
or its users (subprocess.call() etc), it might spend
some considerable time closing non-opened file descriptors,
as demonstrated by the following snippet from strace:
close(3) = -1 EBADF (Bad file descriptor)
close(5) = -1 EBADF (Bad file descriptor)
close(6) = -1 EBADF (Bad file descriptor)
close(7) = -1 EBADF (Bad file descriptor)
...
close(1021) = -1 EBADF (Bad file descriptor)
close(1022) = -1 EBADF (Bad file descriptor)
close(1023) = -1 EBADF (Bad file descriptor)
This happens because the code in _close_fds() iterates from 3 up to
MAX_FDS = os.sysconf("SC_OPEN_MAX").
Now, syscalls are cheap, but SC_OPEN_MAX (also known as RLIMIT_NOFILE
or ulimit -n) can be quite high, for example:
$ docker run --rm python python3 -c \
$'import os\nprint(os.sysconf("SC_OPEN_MAX"))'
1048576
This means a million syscalls before spawning a child process, which
can result in a major delay, like 0.1s as measured on my fast and mostly
idling laptop. Here is the comparison with python3 (which does not have this problem):
$ docker run --rm python python3 -c $'import subprocess\nimport time\ns = time.time()\nsubprocess.check_call([\'/bin/true\'], close_fds=True)\nprint(time.time() - s)\n'
0.0009245872497558594
$ docker run --rm python python2 -c $'import subprocess\nimport time\ns = time.time()\nsubprocess.check_call([\'/bin/true\'], close_fds=True)\nprint(time.time() - s)\n'
0.0964419841766
|
|||
| msg333932 - (view) | Author: Josh Rosenberg (josh.r) * (Python triager) | Date: 2019年01月18日 02:24 | |
Others can correct me if I'm wrong, but I'm fairly sure 2.7 isn't making changes unless they fix critical or security-related bugs. The code here is suboptimal, but it's already been fixed in Python 3 (in #8052), as part of a C accelerator module (that reduces the risk of race conditions and other conflicts your Python level fix entails). Unless someone corrects me, I'll close this as "Won't Fix". |
|||
| msg333940 - (view) | Author: Benjamin Peterson (benjamin.peterson) * (Python committer) | Date: 2019年01月18日 04:56 | |
Yeah, this is WONTFIX particularly since you can have the Python3 implementation in Python 2 easily with https://pypi.org/project/subprocess32/. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022年04月11日 14:59:10 | admin | set | github: 79938 |
| 2019年01月18日 04:56:53 | benjamin.peterson | set | status: open -> closed nosy: + benjamin.peterson messages: + msg333940 resolution: wont fix stage: resolved |
| 2019年01月18日 02:24:17 | josh.r | set | nosy:
+ josh.r messages: + msg333932 |
| 2019年01月17日 04:29:01 | Kirill Kolyshkin | create | |