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
?
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.
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/