2011-06-27 2 views
1

Tous,Exécution d'un Python Subprocess

J'ai lu plusieurs discussions sur la façon de fonctionner en python et sous-processus aucun d'entre eux semblent me aider. C'est probablement parce que je ne sais pas comment les utiliser correctement. J'ai plusieurs méthodes que je voudrais exécuter en même temps plutôt que dans l'ordre et j'ai pensé que le module de sous-processus ferait ceci pour moi.

def services(): 
    services = [method1(), 
      method2(), 
      method3(), 
      mrthod4(), 
      method5()] 
    return services 

def runAll(): 
    import subprocess 
    for i in services(): 
     proc = subprocess.call(i,shell=True) 

Le problème avec cette approche est que méthode1() démarre et method2() ne commence pas avant 1 finitions. J'ai essayé plusieurs approches comprenant l'utilisation de subprocess.Popen [] dans ma méthode de services sans la chance. Quelqu'un peut-il me donner un coup de main sur la façon de faire fonctionner les méthodes 1-5 en même temps?

Merci, Adam

Répondre

1

En python 3.2.x le module concurrent à terme fait ce genre de choses très facile.

4

Selon la documentation Python subprocess.call() attend la commande pour terminer. Vous devriez utiliser directement les objets subprocess.Popen qui vous donneront la flexibilité dont vous avez besoin.

1

Vous devez utiliser & pour les exécuter de manière asynchrone. Voici un exemple:

subprocess.call("./foo1&", shell=True) 
subprocess.call("./foo2&", shell=True) 

Ceci est similaire au shell unix ordinaire.

EDIT: Bien qu'il existe plusieurs façons, bien meilleures. Voir les autres réponses pour quelques exemples.

0

Le sous-processus ne rend pas les processus asynchrones. Ce que vous essayez d'accomplir peut être fait en utilisant le module multithreading ou multi-traitement.

1

En disant method1(), vous appelez la fonction et attendez qu'elle revienne. (Il est une fonction, pas une méthode.)

Si vous voulez juste courir un tas de fonctions lourds en parallèle et recueillir leur résultat, vous pouvez utiliser joblib:

from joblib import Parallel, delayed 

functions = [fn1, fn2, fn3, fn4] 

results = Parallel(n_jobs=4)(delayed(f)() for f in functions) 
1

subprocess.call() blocs jusqu'à la le processus se termine.

multiprocessing semble plus approprié pour ce que vous faites.

par exemple:

from multiprocessing import Process 

def f1(): 
    while True: 
     print 'foo' 

def f2(): 
    while True: 
     print 'bar' 

def f3(): 
    while True: 
     print 'baz' 

if __name__ == '__main__': 
    for func in (f1, f2, f3): 
     Process(target=func).start() 
0

J'ai eu un problème similaire récemment et a résolu le problème comme celui-ci:

from multiprocessing import Pool 
def parallelfuncs(funcs, args, results, bad_value = None): 
    p = Pool() 
    waiters = [] 
    for f in funcs: 
     waiters.append(p.apply_async(f, args, callback = results.append)) 
    p.close() 
    for w in waiters: 
     if w.get()[0] == bad_value: 
      p.terminate() 
    return p 

La bonne chose est que les fonctions funcs sont exécutées en parallèle sur args (genre de l'inverse de la carte), et le résultat est retourné. Le pool de multitraitement utilise tous les processeurs et gère l'exécution des tâches.

w.obtenir des blocs, si ce n'était pas clair.

Pour votre cas d'utilisation, vous appelez

results = [] 
parallelfuncs(services, args, results).join() 
print results 
Questions connexes