python / python/cpython

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

Aperta
#124,706 6 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

topic-multiprocessing type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia riproducendo l'esempio con concurrent.futures.process.ProcessPoolExecutor, quindi leggi concurrent/futures/process.py e i file spawn di multiprocessing a cui si fa riferimento. Traccia il ciclo di vita dell'executor e il comportamento del garbage collector durante creazioni ripetute. Il lavoro è completato quando gli executor creati ripetutamente non esauriscono più i descrittori di file nelle versioni di Python e nel sistema operativo segnalati, con un test di regressione che copra il caso.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
backend
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.