asyncio.subprocess spawning can block
Ninguém assumiu esta issue ainda.
- Linguagem predominante
- Python
- Estrelas
- 77.2k
- Forks
- 35.9k
- Métricas de merge de PRs
- Métricas de PR pendentes
Descrição
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
Guia de contribuição
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Direção de pesquisa
Rastreie o caminho de chamadas de _make_subprocess_transport() em Lib/asyncio/unix_events.py passando por Lib/asyncio/base_subprocess.py e subprocess.Popen() em Lib/subprocess.py. Revise o trabalho vinculado a gh-154111 antes de prosseguir; a conclusão deve impedir que a inicialização de subprocess bloqueie o loop de eventos e incluir cobertura de regressão para o comportamento relatado.
Escrita pelo modelo de indexação a partir do texto da issue.
Avaliação
- Stack de tecnologia
- python
- Domínio
- operating-systems
- Tipo de issue
- Bug
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Status de atividade
- Estagnada
- Clareza
- Precisa de esclarecimento
- Facilidade para iniciantes
- 30/100