在Python多处理中,为什么子进程名称是__mp_main__?有没有办法用自定义名称覆盖它?

Paw*_*wan 2 python multiprocessing python-multiprocessing

#!/usr/bin/env python3

import multiprocessing as mp


def child_process():
    print('Hi! My name is', __name__)


print('Hi! My name is', __name__)
if __name__ == '__main__':
    mp.Process(target=child_process).start()

Run Code Online (Sandbox Code Playgroud)

上面的代码输出如下: 上述代码的控制台输出

我很困惑

  1. 为什么是子进程名称__mp_main__
  2. 为什么要打印两次?

Blc*_*ght 6

您很困惑,因为您在两个不同的地方打印相同的消息。如果您提供不同的打印输出,您会更好地了解发生了什么:

import multiprocessing as mp

def child_process():
    print('Function print from:', __name__)

print('Top level print from:', __name__)

if __name__ == '__main__':
    mp.Process(target=child_process).start()
Run Code Online (Sandbox Code Playgroud)

使用此代码,您将得到:

import multiprocessing as mp

def child_process():
    print('Function print from:', __name__)

print('Top level print from:', __name__)

if __name__ == '__main__':
    mp.Process(target=child_process).start()
Run Code Online (Sandbox Code Playgroud)

现在您可以看到第一个打印输出来自运行顶层代码的主模块。然后子进程被启动,并且它还运行顶层代码。然后多处理逻辑在子进程内运行该函数,您将得到第三行。

模块在子进程中再次加载可能会让人感到惊讶,但这是使用模式(spawn默认模式)时 Python 多处理设计的一部分。顶层代码再次运行,但不是由 保护的部分if __name__ == "__main__",因为__name____mp_main__。不同的名称是故意的,以防止所有代码(包括启动另一个子进程)在子进程中再次运行。让每个子进程也生成另一个进程会对您的系统造成不良影响,因为您将创建无限数量的进程。

另一件值得理解的事情是:__name__全局变量不是进程的名称,而是当前模块的名称。如果您要访问import包含上述代码的模块,它将打印出实际的模块名称,而不是__main____mp_main__,它们是分别用于作为脚本运行的模块和子进程中的同一模块的特殊名称。Dan Constantinescu给出了一个很好的答案,解释了如何打印出实际的进程名称(如果您想要的话)。