Есть ли способ зарегистрировать вывод stdout из данного Процесса при использовании многопроцессорного процесса. КлассProcess в python?
Вывод журнала многопроцессорности. Процесс
Ответ 1
Самый простой способ - просто переопределить 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
Ответ 2
Вы можете установить sys.stdout = Logger()
, где Logger
- это класс, метод write
которого (сразу или накапливается до обнаружения \n
) вызывает logging.info
(или любой другой способ, которым вы хотите регистрироваться). Пример этого в действии.
Я не уверен, что вы подразумеваете под "определенным" процессом (кто его дал, что отличает его от всех других...?), но если вы имеете в виду, что знаете, какой процесс вы хотите выделить таким образом время, которое вы его создаете, тогда вы можете обернуть его target
функцию (и только) - или метод run
, который вы переопределяете в подклассе Process
- в оболочку, которая выполняет этот sys.stdout "перенаправление" - и оставить другие процессы в покое.
Возможно, если вы немного приглушите спецификации, я могу помочь более подробно...?
Ответ 3
Есть только две вещи, которые я бы добавил к ответу @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 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'