Доступ к стандартному выводу подпроцесса в 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
в противном случае ничего не будет записано в очередь.