日志输出multiprocessing.Process


Answers:


59

最简单的方法可能是覆盖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
py
$ python m.py
$ ls
27493.out 27494.out m.py
$ cat 27493.out 
函数f
模块名称:__ main__
父进程:27492
进程编号:27493
你好鲍勃
$ cat 27494.out 
函数f
模块名称:__ main__
父进程:27492
进程编号:27494
你好弗雷德


20

我只会在@Mark Rushakoff答案中添加两件事。调试时,我发现将调用的buffering参数更改open()为0确实很有用。

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

否则为madness,因为在tail -f输出文件时,结果可能会断断续续。buffering=0tail -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'

继承人的要点


5
我在python 3.6中尝试此操作时遇到ValueError,因为buffering = 0仅允许用于二进制模式。但是,您可以通过从sys.stdout / stderr的猴子补丁中删除buffering = 0并在输出语句中添加flush = True来解决此问题。即print(“ Stdout初始化”,flush = True)。它像一种魅力。
JMDE

意识到打开的文件没有被关闭。这会是个问题吗?
田”

12

您可以设置sys.stdout = Logger()在哪里调用Loggerwrite方法(立即或\n在检测到a之前累积)的类logging.info(或要记录的任何其他方式)。一个实际的例子。

我不确定您所说的“给定”过程的含义(给定的是谁,有什么区别于其他所有事物的??),但是如果您的意思是知道自己当时想以哪种方式选出哪个过程,实例化它,然后就可以包装它的target功能(且仅此包装)-或runProcess子类中包装到执行sys.stdout“重定向”的包装器中,而不必处理其他进程。

也许如果您确定一下规格,我可以提供更多详细信息...?


3

这是捕获stdout以便进行multiprocessing.Processio.TextIOWrapper的简单 明了

import app
import io
import sys
from multiprocessing import Process


def run_app(some_param):
    out_file = open(sys.stdout.fileno(), 'wb', 0)
    sys.stdout = io.TextIOWrapper(out_file, write_through=True)
    app.run()

app_process = Process(target=run_app, args=('some_param',))
app_process.start()
# Use app_process.termninate() for python <= 3.7.
app_process.kill() 

这并不能够作为应用重定向的改变正在运行
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.