【问题标题】:Understanding .fork() with multiprocessing and logging使用多处理和日志了解 .fork()
【发布时间】:2021-12-28 21:11:32
【问题描述】:

我正在运行一个多处理池,它记录到由主父进程配置的记录器。在一种情况下,我有

def init():
  global LOG
  LOG = logging.getLogger(__name__)
  LOG.setLevel(logging.DEBUG)

def main():
  LOG.info("test")

if __name__ == '__main__':
  fmt = "%(asctime)s %(name)s %(levelname)s: %(message)s"
  logging.basicConfig(format=fmt, datefmt='%m/%d/%Y %I:%M:%S %p')
  with multiprocessing.Pool(initializer = init) as pool:
    pool.map(main, inputs)

没有任何东西被打印到我的主调用线程的标准输出。但是,如果我这样做:

fmt = "%(asctime)s %(name)s %(levelname)s: %(message)s"
logging.basicConfig(format=fmt, datefmt='%m/%d/%Y %I:%M:%S %p')

def init():
  global LOG
  LOG = logging.getLogger(__name__)
  LOG.setLevel(logging.DEBUG)

def main():
  LOG.info("test")

if __name__ == '__main__':
  with multiprocessing.Pool(initializer = init) as pool:
    pool.map(main, inputs)

然后我确实有正确的日志记录。我不明白为什么这两件事不同。当 python 派生到工作进程时,子进程应该与父进程相同,因此我们是否在全局命名空间中调用 logging.basicConfig 与主执行块之间没有区别。有人可以澄清一下吗?

【问题讨论】:

  • 碰巧你是在 Windows 上运行吗?
  • MacOs 也是如此,实际上,因为它也使用 spawn 而不是 fork
  • 在 MacOSX 上运行

标签: python logging multiprocessing


【解决方案1】:

您的代码非常适合 Linux-es(除了它甚至无法运行,哈哈)

但是对于 Windows 和 OSX,multiprocessing 会产生一个新的解释器(参见the docs)并会尝试导入目标模块。这是您的__name__ == '__main__' 守卫发挥作用的分叉(双关语)点——您的logging 设置根本没有在衍生的工人中完成!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 2020-12-07
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 2022-01-03
    相关资源
    最近更新 更多