python / python/cpython

Repeated creation of ProcessPoolExecutor leads to "Too many open files"

Aberta
#124,706 6 comentários 0 reações 0 responsáveis Ver no GitHub

Ninguém assumiu esta issue ainda.

topic-multiprocessing type-bug
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:

Running this code:

import concurrent.futures.process
for _ in range(100):
    x = concurrent.futures.process.ProcessPoolExecutor()
    x.submit(lambda: 42)

Results (most of the time) in an error indicating the system has run out of file descriptors, for example:

Traceback (most recent call last):
  File "<python-input-3>", line 4, in <module>
    x.submit(lambda: 42)
    ~~~~~~~~^^^^^^^^^^^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/concurrent/futures/process.py", line 811, in submit
    self._adjust_process_count()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/concurrent/futures/process.py", line 770, in _adjust_process_count
    self._spawn_process()
    ~~~~~~~~~~~~~~~~~~~^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/concurrent/futures/process.py", line 788, in _spawn_process
    p.start()
    ~~~~~~~^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/multiprocessing/process.py", line 121, in start
    self._popen = self._Popen(self)
                  ~~~~~~~~~~~^^^^^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/multiprocessing/context.py", line 289, in _Popen
    return Popen(process_obj)
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/multiprocessing/popen_spawn_posix.py", line 32, in __init__
    super().__init__(process_obj)
    ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/multiprocessing/popen_fork.py", line 20, in __init__
    self._launch(process_obj)
    ~~~~~~~~~~~~^^^^^^^^^^^^^
  File "/Users/jelle/.pyenv/versions/3.13.0rc2/lib/python3.13/multiprocessing/popen_spawn_posix.py", line 53, in _launch
    parent_r, child_w = os.pipe()
                        ~~~~~~~^^
OSError: [Errno 24] Too many open files

The exact error varies. For example, one time the error happened on an os.getcwd() call. One time one of the futures printed as <Future at 0x1035b9950 state=finished raised PicklingError>.

I originally encountered this in the CI for Black, where it only happened on MacOS in 3.13, but the code sample above raises errors on 3.11 and 3.12 too when I run it locally. Still, it's possible that the GC changes in 3.13 make the problem more frequent.

Adding gc.collect() to the loop body fixes the problem. This suggests there is some cycle involving the executor that isn't getting collected until the GC kicks in.

CPython versions tested on:

3.11, 3.12, 3.13

Operating systems tested on:

macOS

Guia de contribuição

Abrir o guia de contribuição

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Direção de pesquisa

Comece reproduzindo o exemplo com concurrent.futures.process.ProcessPoolExecutor e, em seguida, leia concurrent/futures/process.py e os arquivos spawn de multiprocessing referenciados. Rastreie o ciclo de vida do executor e o comportamento da coleta de lixo em torno de criações repetidas. O trabalho estará concluído quando executors criados repetidamente não esgotarem mais os descritores de arquivo nas versões do Python e no sistema operacional reportados, com um teste de regressão cobrindo o caso.

Escrita pelo modelo de indexação a partir do texto da issue.

Avaliação

Stack de tecnologia
python
Domínio
backend
Tipo de issue
Bug
Dificuldade
4/5
Tempo estimado
3-5 dias
Status de atividade
Estagnada
Clareza
Precisa de esclarecimento
Facilidade para iniciantes
35/100

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.