繁体   English   中英

Python:如何为 multiprocessing.Pool 中的进程使用不同的日志文件?

[英]Python: How to use different logfiles for processes in multiprocessing.Pool?

我正在使用multiprocessing.Pool并行运行多个独立进程。 与 python 文档中的基本示例没有太大区别:

from multiprocessing import Pool

def f(x):
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, [1, 2, 3]))

我希望每个进程都有一个单独的日志文件。 我在我的代码库和一些第三方包中记录了来自其他模块的各种信息(它们都不支持多处理)。 所以,例如,我想要这样:

import logging
from multiprocessing import Pool

def f(x):
    logging.info(f"x*x={x*x}")
    return x*x

if __name__ == '__main__':
    with Pool(5) as p:
        print(p.map(f, range(10)))

在磁盘上写:

log1.log
log2.log
log3.log
log4.log
log5.log

我如何实现它?

您需要在工作人员启动后立即使用 Pool 的initializer()设置和注册单独的记录器。 在后台, Pool(initializer)Pool(initargs)的参数最终被传递给Process(target)Process(args)以创建新的工作进程......

Pool-workers 以 {start_method}PoolWorker-{number} 的格式命名,例如SpawnWorker-1 ,如果您使用 spawn 作为新进程的启动方法。 然后可以使用mp.current_process().name.split('-')[1]从分配的工作人员名称中提取日志文件的文件编号。

import logging
import multiprocessing as mp


def f(x):
    logger.info(f"x*x={x*x}")
    return x*x


def _init_logging(level=logging.INFO, mode='a'):
    worker_no = mp.current_process().name.split('-')[1]
    filename = f"log{worker_no}.log"
    fh = logging.FileHandler(filename, mode=mode)
    fmt = logging.Formatter(
        '%(asctime)s %(processName)-10s %(name)s %(levelname)-8s --- %(message)s'
    )
    fh.setFormatter(fmt)
    logger = logging.getLogger()
    logger.addHandler(fh)
    logger.setLevel(level)
    globals()['logger'] = logger


if __name__ == '__main__':

    with mp.Pool(5, initializer=_init_logging, initargs=(logging.DEBUG,)) as pool:
        print(pool.map(f, range(10)))

请注意,由于多处理的性质,无法保证您在小示例中最终得到的文件的确切数量。 由于multiprocessing.Pool (与concurrent.futures.ProcessPoolExecutor相反)在您创建实例后立即启动工作人员,因此您一定会获得指定的Pool(process)文件数,因此在您的情况下为 5. 实际线程/进程- 不过,由您的操作系统安排可能会缩短这个数字。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM