Existe-t-il un moyen de consigner la sortie stdout d'un processus donné lors de l'utilisation de la classe multiprocessing.Process en python?
Le moyen le plus simple pourrait être de simplement remplacer sys.stdout
. Modifiant légèrement un exemple de le manuel de multitraitement :
from multiprocessing import Process
import os
import sys
def info(title):
print title
print 'module name:', __name__
print 'parent process:', os.getppid()
print 'process id:', os.getpid()
def f(name):
sys.stdout = open(str(os.getpid()) + ".out", "w")
info('function f')
print 'hello', name
if __== '__main__':
p = Process(target=f, args=('bob',))
p.start()
q = Process(target=f, args=('fred',))
q.start()
p.join()
q.join()
Et l'exécuter:
$ ls m.py $ python m.py $ ls 27493.out 27494 .out m.py $ cat 27493.out fonction f nom du module: __main __ processus parent: 27492 id du processus: 27493 hello bob $ cat 27494.out fonction f nom du module: __main __ processus parent: 27492 id de processus: 27494 bonjour fred
Il n'y a que deux choses que j'ajouterais à la réponse de @Mark Rushakoff. Lors du débogage, j'ai trouvé très utile de changer le paramètre buffering
de mes appels open()
à 0.
sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)
Sinon, folie , car quand tail -f
dans le fichier de sortie, les résultats peuvent être verrouillés par intermittence. buffering=0
pour tail -f
très bien.
Et pour être complet, rendez-vous service et redirigez sys.stderr
ainsi que.
sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)
De plus, pour plus de commodité, vous pouvez les vider dans une classe de processus distincte si vous le souhaitez,
class MyProc(Process):
def run(self):
# Define the logging in run(), MyProc's entry function when it is .start()-ed
# p = MyProc()
# p.start()
self.initialize_logging()
print 'Now output is captured.'
# Now do stuff...
def initialize_logging(self):
sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)
sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)
print 'stdout initialized'
Vous pouvez définir sys.stdout = Logger()
où Logger
est une classe dont la méthode write
(immédiatement, ou accumulée jusqu'à ce que \n
est détecté) appelle logging.info
(ou tout autre moyen de connexion). n exemple de ceci en action.
Je ne sais pas ce que vous entendez par un processus "donné" (qui le donne, qu'est-ce qui le distingue de tous les autres ...?), Mais si vous voulez dire que vous savez quel processus vous voulez distinguer de cette façon au moment où vous instanciez-le, vous pouvez ensuite envelopper sa fonction target
(et cela seulement) - ou la méthode run
que vous remplacez dans une sous-classe Process
- dans un wrapper qui effectue cette "redirection" sys.stdout - et laisse les autres processus seuls.
Peut-être que si vous fixez un peu les spécifications, je peux vous aider plus en détail ...?