web-dev-qa-db-fra.com

le multitraitement renvoie "trop ​​de fichiers ouverts" mais l'utilisation de "avec ... comme" le corrige. Pourquoi?

J'utilisais cette réponse afin d'exécuter des commandes parallèles avec multiprocessing dans Python sur une boîte Linux).

Mon code a fait quelque chose comme:

import multiprocessing
import logging

def cycle(offset):
    # Do stuff

def run():
    for nprocess in process_per_cycle:
        logger.info("Start cycle with %d processes", nprocess)
        offsets = list(range(nprocess))
        pool = multiprocessing.Pool(nprocess)
        pool.map(cycle, offsets)

Mais je recevais cette erreur: OSError: [Errno 24] Too many open files
Donc, le code ouvrait trop de descripteurs de fichiers, c'est-à-dire: il commençait trop de processus et ne les terminait pas.

Je l'ai corrigé en remplaçant les deux dernières lignes par ces lignes:

    with multiprocessing.Pool(nprocess) as pool:
        pool.map(cycle, offsets)

Mais je ne sais pas exactement pourquoi ces lignes l'ont corrigé.

Que se passe-t-il en dessous de ce with?

12
nephewtom

Vous créez de nouveaux processus dans une boucle, puis oubliez de les fermer une fois que vous en avez terminé. En conséquence, il arrive un moment où vous avez trop de processus ouverts. C'est une mauvaise idée.

Vous pouvez résoudre ce problème en utilisant un gestionnaire de contexte qui appelle automatiquement pool.terminate, ou appelez manuellement pool.terminate toi même. Sinon, pourquoi ne créez-vous pas un pool en dehors de la boucle une seule fois , puis envoyez des tâches aux processus à l'intérieur?

pool = multiprocessing.Pool(nprocess) # initialise your pool
for nprocess in process_per_cycle:
    ...       
    pool.map(cycle, offsets) # delegate work inside your loop

pool.close() # shut down the pool

Pour plus d'informations, vous pouvez parcourir les multiprocessing.Pool documentation.

11
cs95

C'est un gestionnaire de contexte. L'utilisation de avec garantit que vous ouvrez et fermez correctement les fichiers. Pour comprendre cela en détail, je recommanderais cet article https://jeffknupp.com/blog/2016/03/07/python-with-context-managers/

1
pritesh