web-dev-qa-db-fra.com

Est-il possible d'exécuter une fonction dans un sous-processus sans enfiler ou écrire un fichier / script séparé.

import subprocess

def my_function(x):
    return x + 100

output = subprocess.Popen(my_function, 1) #I would like to pass the function object and its arguments
print output 
#desired output: 101

Je n'ai trouvé que de la documentation sur l'ouverture de sous-processus à l'aide de scripts séparés. Quelqu'un sait-il comment passer des objets de fonction ou même un moyen simple de passer du code de fonction?

55
wroscoe

Je pense que vous cherchez quelque chose de plus comme le module multiprocesseur:

http://docs.python.org/library/multiprocessing.html#the-process-class

Le module de sous-processus sert à générer des processus et à faire des choses avec leur entrée/sortie - pas pour exécuter des fonctions.

Voici une version multiprocessing de votre code:

from multiprocessing import Process, Queue

def my_function(q, x):
    q.put(x + 100)

if __== '__main__':
    queue = Queue()
    p = Process(target=my_function, args=(queue, 1))
    p.start()
    p.join() # this blocks until the process terminates
    result = queue.get()
    print result
82
Brian McKenna

Vous pouvez utiliser l'appel système Unix fork standard, comme os.fork() . fork() créera un nouveau processus, avec le même script en cours d'exécution. Dans le nouveau processus, il renverra 0, tandis que dans l'ancien processus, il renverra l'ID de processus du nouveau processus.

child_pid = os.fork()
if child_pid == 0:
  print "New proc"
else:
  print "Old proc"

Pour une bibliothèque de niveau supérieur, qui fournit un support multiprocessing qui fournit une abstraction portable pour l'utilisation de plusieurs processus, il y a le module multiprocessing . Il y a un article sur IBM DeveloperWorks, Multiprocessing with Python , avec une brève introduction aux deux techniques.

13
Brian Campbell

Le message ci-dessus de Brian McKenna sur le multitraitement est vraiment utile, mais si vous vouliez emprunter la route filetée (par opposition au processus), cet exemple vous aidera à démarrer:

import threading
import time

def blocker():
    while True:
        print "Oh, sorry, am I in the way?"
        time.sleep(1)

t = threading.Thread(name='child procs', target=blocker)
t.start()

# Prove that we passed through the blocking call
print "No, that's okay" 

Vous pouvez également utiliser la fonction setDaemon(True) pour mettre immédiatement le thread en arrière-plan.

5
user559633