Выход журнала многопроцессорной обработки. Процесс - PullRequest
61 голосов
/ 01 октября 2009

Есть ли способ записать вывод stdout из данного процесса при использовании класса multiprocessing.Process в python?

Ответы [ 3 ]

50 голосов
/ 01 октября 2009

Самый простой способ - просто переопределить sys.stdout. Немного модифицировав пример из многопроцессорного руководства :

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()

И запустить его:

$ ls
m.py
$ python m.py
$ ls
27493.out  27494.out  m.py
$ cat 27493.out 
function f
module name: __main__
parent process: 27492
process id: 27493
hello bob
$ cat 27494.out 
function f
module name: __main__
parent process: 27492
process id: 27494
hello fred

14 голосов
/ 29 мая 2014

Есть только две вещи, которые я бы добавил к ответу @Mark Rushakoff. При отладке я нашел действительно полезным изменить параметр buffering моих вызовов open() на 0.

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

В противном случае, безумие , потому что при tail -f в выходном файле результаты могут быть прерывистыми buffering=0 для tail -f отлично.

И для полноты, сделайте себе одолжение и перенаправьте также sys.stderr.

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

Кроме того, для удобства вы можете сбросить это в отдельный класс процесса, если хотите,

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'

Вот соответствующий гист

11 голосов
/ 01 октября 2009

Вы можете установить sys.stdout = Logger(), где Logger - это класс, метод которого write (немедленно или накапливающийся до обнаружения \n) вызывает logging.info (или любой другой способ входа в систему). Пример этого в действии.

Я не уверен, что вы подразумеваете под "данным" процессом (кто его дал, что отличает его от всех других ...?), Но если вы имеете в виду, вы знаете, какой процесс вы хотите выделить таким образом при когда вы создаете его экземпляр, вы можете обернуть его функцию target (и это только) - или метод run, который вы переопределяете в подклассе Process, - в оболочку, которая выполняет этот sys.stdout " перенаправление "- и оставьте другие процессы в покое.

Может быть, если вы немного прибавите спецификации, я могу помочь более подробно ...?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...