为什么伐木.记录器在Windows上的新进程中重置其状态



我在Windows上的python日志记录模块中遇到了奇怪的问题。下面的代码显示了它:

import multiprocessing
import logging
import sys

class ProcessLogger(multiprocessing.Process):
    def __init__(self):
        super().__init__()
        self.create_logger()
        print('state of logger in main proccess:')
        print(self.logger)
        print(self.logger.handlers)
    def run(self):
        print('state of logger in child proccess:')
        print(self.logger)
        print(self.logger.handlers)
    def create_logger(self):
        self.logger = logging.getLogger('something')
        self.logger.setLevel(logging.DEBUG)
        handler = logging.StreamHandler()
        self.logger.addHandler(handler)

if __name__ == '__main__':
    logg = ProcessLogger()
    logg.start()
    logg.join()
    print(sys.version)

它在Windows上打印以下输出:

state of logger in main proccess:
<Logger something (DEBUG)>
[<StreamHandler <stderr> (NOTSET)>]
state of logger in child proccess:
<Logger something (WARNING)>
[]
3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)]

由于某种原因,新进程中的记录器对象具有默认状态。

我在 ubuntu 上尝试过这个,它似乎按预期工作:

state of logger in main proccess:
<Logger something (DEBUG)>
[<StreamHandler <stderr> (NOTSET)>]
state of logger in child proccess:
<Logger something (DEBUG)>
[<StreamHandler <stderr> (NOTSET)>]
3.7.1 (default, Oct 22 2018, 11:21:55) 
[GCC 8.2.0]

这是窗口上的预期行为吗?有人可以解释一下吗?

您在两个操作系统上观察到上述行为的原因是由于fork(Unix(和spawn(Windows(进程启动策略之间的差异。

使用 fork 策略,将创建子进程作为父进程的精确克隆。这两个进程首先是相同的,子进程将共享父进程的所有属性(打开的文件、配置选择等(。

相反,使用spawn策略将启动新的空白流程。该进程被赋予要加载的 Python 模块,并指向要在 run 方法中执行的第一条指令。父级事先执行的所有操作都不会继承。

相关内容

  • 没有找到相关文章

最新更新