83 votes

Consigner la sortie du multitraitement.Process

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?

71voto

Mark Rushakoff Points 97350

La façon la plus simple pourrait être de substituer sys.stdout. Modifiant légèrement un exemple de la multitraitement manuel:

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 __name__ == '__main__':
    p = Process(target=f, args=('bob',))
    p.start()
    q = Process(target=f, args=('fred',))
    q.start()
    p.join()
    q.join()

Et en l'exécutant:

$ ls
m.py
$ python m.py
$ ls
27493.hors 27494.s.py
$ cat 27493.hors 
la fonction f
nom du module: __principaux__
processus père: 27492
id de processus: 27493
bonjour bob
$ cat 27494.hors 
la fonction f
nom du module: __principaux__
processus père: 27492
id de processus: 27494
bonjour fred

24voto

HeyWatchThis Points 2221

Il y a seulement deux choses que je voudrais ajouter à @Mark Rushakoff réponse. Lors du débogage, je l'ai trouvé vraiment utile de changer l' buffering paramètre de mon open() appels à 0.

sys.stdout = open(str(os.getpid()) + ".out", "a", buffering=0)

Sinon, la folie, parce que quand tail -fing le fichier de sortie, les résultats peuvent être extrêmement intermittent. buffering=0 pour tail -fing grande.

Et pour être exhaustif, faites-vous une faveur et de les rediriger sys.stderr ainsi.

sys.stderr = open(str(os.getpid()) + "_error.out", "a", buffering=0)

Aussi, pour plus de commodité, vous pourriez dump que dans un processus distinct de la classe 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'

Heres un correspondant gist

14voto

Alex Martelli Points 330805

Vous pouvez configurer sys.stdout = Logger()Logger est une classe dont write méthode (immédiatement, ou accumulant jusqu'à un \n est détecté) appels logging.info (ou de toute autre manière que vous voulez vous connecter).

Je ne suis pas sûr de ce que tu veux dire par "un" processus (qui est donné, ce qui la distingue de toutes les autres...?), mais si vous voulez dire que vous savez ce processus, vous voulez sortir de cette façon, au moment de l'instanciation, alors vous pouvez l'envelopper de ses target de la fonction (et uniquement), ou l' run méthode de remplacement dans un Process sous-classe -- dans une enveloppe qui effectue ce sys.stdout "redirection" -- et laisser les autres procédés seul.

Peut-être que si vous clouer le specs un peu je peux vous aider plus en détail...?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X