2014-05-01 4 views
1

J'utilise actuellement des fonctions de multi-traitement pour analyser environ 10 fichiers.Le multitraitement Python n'attend pas

Cependant, je veux seulement exécuter 5 processus à chaque fois. Lorsque j'essaie d'implémenter ceci, cela ne fonctionne pas. Plus de processus sont créés puis le nombre que j'ai spécifié. Y at-il un moyen qui limite facilement le nombre de processus à 5? (Windows 7/Python 2.7)

EDIT: J'ai peur que vos solutions ne fonctionnent toujours pas. Je vais essayer d'afficher plus de détails ici;

Fichier python principal;

import python1 
import python2 
import multiprocessing 

# parallel = [fname1, fname2, fname3, fname4, fname5, fname6, fname7, fname8, fname9, fname10] 
if name == '__main__': 
    pool = multiprocessing.Pool(processes=max(len(parallel), 5)) 
    print pool.map(python1.worker, parallel) 

Fichier Python1; L'instruction return de 12 fichiers revient avant que tous les modules perl ouverts soient fermés. En outre 12 coquilles perl sont ouvertes au lieu de seulement le maximum de 5. (Image; Vous pouvez voir clairement que les déclarations de retour reviennent avant que les commandes de perl finissent même, et il y a plus de 5 processus http://oi57.tinypic.com/126a8ht.jpg)

Répondre

0

Je sais pourquoi c'est un secret ce qui ne se passe pas exactement et ce qui se passe à la place.

Et de fournir un SSCCE signifie un programme qui fonctionne réellement. (Jetez un oeil à la fonction worker(), par exemple. Il obtient un paramètre file qui est jamais utilisé, et utilise une variable command qui est définie nulle part.)

Mais je pense qu'il est le point que votre fileX sont fichier juste noms et ils sont tentés d'être exécutés.

Changer votre fonction

def worker(filename): 
    command = "echo X " + filename + " Y" 
    os.system(command) 

et il devrait fonctionner correctement. (Notez que j'ai changé file-filename afin de ne pas cacher un nom intégré.)

BTW, au lieu de os.system() vous devez utiliser le module subprocess.

Dans ce cas, vous pouvez faire

import subprocess 

def worker(filename): 
    command = ["echo", "X", filename, "Y"] 
    subprocess.call(command) 

qui devrait faire la même chose.

Tout comme une remarque stylistique:

pool = multiprocessing.Pool(processes=max(len(parallel), 5)) 

est plus simple et fait la même chose.


Votre modification rend le problème beaucoup plus clair maintenant.

Il semble que, pour des raisons inconnues, vos programmes perl sortent plus tôt qu'ils ne sont vraiment terminés. Je ne sais pas pourquoi cela se produit - peut-être qu'ils fourchent un autre processus par eux-mêmes et sortent immédiatement. Ou c'est dû aux fenêtres et à ses bizarreries.

Dès que le pool de multitraitement constate qu'un sous-processus se termine, il est prêt à en lancer un autre. Donc, la bonne façon serait de savoir pourquoi les programmes Perl ne fonctionnent pas comme prévu.

+0

Votre méthode n'a pas fonctionné pour moi. J'ai posté plus de détails dans ma question principale. (Peut-être que je devrais avoir mentionné que j'ai importé d'autres fichiers python, excuses pour cela) – user3589561

0

J'ai essayé avec le code suivant sous Linux avec python-2.7 et il ne l'affirme pas. Seulement 5 processus sont créés à la fois.

import os 
import multiprocessing 
import psutil 
from functools import partial 

def worker(pid, filename): 
# assert len(psutil.Process(pid).children(recursive=True)) == 5 # for psutil-2.x 
    assert len(psutil.Process(pid).get_children(recursive=True)) == 5 
    print(filename) 

parallel = range(0, 15) 

if __name__ == '__main__': 
# with multiprocessing.Pool(processes=5) as pool: # if you use python-3 
    pool = multiprocessing.Pool(processes=min(len(parallel), 5)) 
    pool.map(partial(worker, os.getpid()), parallel) 

Bien sûr, si vous utilisez os.system() dans la fonction de travailleur, il va créer des processus supplémentaires et l'arborescence des processus ressemblera (en utilisant os.system (« sleep 1 ») ici)

\_ python2.7 ./test02.py 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
    | \_ sh -c sleep 1 
    |  \_ sleep 1 
    \_ python2.7 ./test02.py 
     \_ sh -c sleep 1 
      \_ sleep 1 
+0

Votre méthode n'a pas fonctionné pour moi. J'ai posté plus de détails dans ma question principale. (Peut-être aurais-je dû mentionner que j'ai importé d'autres fichiers python, excuses pour cela) – user3589561

+0

Ce n'est pas, en soi, 'ma méthode'. C'est comme ça que fonctionne le multitraitement. Essayez ce code sans votre script Perl. Si cela fonctionne, votre problème vient du script Perl qui crée des sous-processus détachés. – ticapix