Доступ к стандартному выводу подпроцесса в python

Как я могу получить доступ к stdout дочерних процессов перед отправкой их в основной процесс? Я использую модуль multiprocessing.Pool для генерации дочерних пулов процессов.

1 ответ

Основной процесс и дочерние элементы используют одни и те же стандартные дескрипторы входных и стандартных выходных файлов. Они не контролируют то, что им пишет другой. Единственное, что вы можете сделать, это заменить stdin а также stdout у детей с чем-то еще, что основной процесс может контролировать. В качестве примера вы можете создать подкласс фиктивного файлового объекта, такого как StringIO и перенаправить данные, которые дети записывают в этот объект, к родителю через Queue:

import sys
from multiprocessing import Queue, Pool, current_process
from StringIO import StringIO

class MyStringIO(StringIO):
    def __init__(self, queue, *args, **kwargs):
        StringIO.__init__(self, *args, **kwargs)
        self.queue = queue
    def flush(self):
        self.queue.put((current_process().name, self.getvalue()))
        self.truncate(0)

def initializer(queue):
     sys.stderr = sys.stdout = MyStringIO(queue)

def task(num):
     print num
     sys.stdout.flush()
     return num ** 2

q = Queue()
pool = Pool(3, initializer, [q])

for _ in pool.map(task, range(5)):
    proc, out = q.get()
    print proc, "got", out

Это должно напечатать что-то вроде этого:

PoolWorker-1 got 0
PoolWorker-1 got 3
PoolWorker-1 got 4
PoolWorker-2 got 1
PoolWorker-3 got 2

Не забудьте позвонить sys.{stdout,stderr}.flush() в конце task в противном случае ничего не будет записано в очередь.

Другие вопросы по тегам