asyncio.subprocess spawning can block
还没有人认领这个 Issue。
- 主要语言
- Python
- 星标
- 77.2k
- 派生
- 35.9k
- PR 合并指标
- PR 指标待抓取
描述
Bug report
Bug description:
asyncio.create_subprocess_exec() and asyncio.create_subprocess_shell() call subprocess.Popen() synchronously on the event loop thread. Popen._execute_child() performs a blocking os.read() on a CLOEXEC error pipe (Lib/subprocess.py, current main line 1995) that doesn't return until the child completes execve(). This blocks the event loop for the duration of:
fork()/posix_spawn()— page-table duplication proportional to parent process size- Child-side setup (signal disposition, fd operations,
chdir, uid/gid changes) execve()— kernel loads the binary, maps pages before applying O_CLOEXEC
The call chain on the event loop thread is:
_make_subprocess_transport() [async — Lib/asyncio/unix_events.py:197]
→ _UnixSubprocessTransport.__init__() [sync]
→ BaseSubprocessTransport.__init__() [sync — Lib/asyncio/base_subprocess.py:40]
→ self._start() [sync]
→ subprocess.Popen() [sync]
→ _execute_child() [sync — Lib/subprocess.py:1878]
→ os.read(errpipe_read, 50000) [BLOCKS — line 1995]
In production, we have observed this blocking the event loop for multiple seconds when a Python process spawns a large binary (with a substantial statically-linked dependency set) on a system that was within operational parameters for memory usage (no ongoing swapping or similar) but subject to IO read contention slowing the binary-loading process.
The original python/asyncio#414 identified this in 2016; the asyncio repo was archived without resolution or migration to cpython's tracker.
#81444 would serve to fix this issue (by having asyncio.subprocess dispatch to a thread). However, I'm not sure it constitutes the only fix, or even an ideal fix — we should be able to watch for the FIFO either closing or having data available to read using natively asynchronous syscalls.
Observed in production on Python 3.13; determination that the issue still exists in 3.14 and current main based on source tree inspection.
CPython versions tested on:
3.13
Operating systems tested on:
Linux
Linked PRs
- gh-154111
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
追踪从 Lib/asyncio/unix_events.py 中的 _make_subprocess_transport(),经过 Lib/asyncio/base_subprocess.py 和 Lib/subprocess.py 中的 subprocess.Popen() 的调用路径。在继续之前,审查已链接的 gh-154111 工作;完成后应防止 subprocess 启动阻塞事件循环,并包含针对所报告行为的回归测试覆盖。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- python
- 领域
- operating-systems
- Issue 类型
- 缺陷
- 难度
- 5/5
- 预计耗时
- 一周以上
- 活跃度
- 停滞
- 描述清晰度
- 需要澄清
- 新手友好度
- 30/100