Home > OS >  In Python multiprocessing, why is child process name __mp_main__? Is there a way to override it with
In Python multiprocessing, why is child process name __mp_main__? Is there a way to override it with

Time:06-04

#!/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()

The above code output it as below: Console output from the above code

I am confused about

  1. Why the child process name is mp_main?
  2. Why is it printed twice?

CodePudding user response:

You are confusing yourself because you're printing the same message in two different places. If you give distinct printouts, you'll understand better what is going on:

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()

With this code, you'll get:

Top level print from: __main__
Top level print from: __mp_main__
Function print from: __mp_main__

Now you can see that the first printout is from the main module running the top level code. Then the child process is launched, and it also runs the top level code. Then the multiprocessing logic runs the function inside the child process, and you get the third line.

It may come as a surprise that the module is loaded again in the child process, but it's part of the design of Python's multiprocessing when using the spawn mode (which is the default). The top level code runs again, but not the part guarded by if __name__ == "__main__", since __name__ is __mp_main__. The different name is deliberate, to prevent all the code (including launching another child) from running again in the child process. Having each child also spawn another process would do bad things to your system, since you'd be creating an unlimited number of processes.

Another thing worth understanding: The __name__ global variable isn't the name of the process, it's the name of the current module. If you were to import the module containing the code above, it would print out the actual module name, rather than either __main__ or __mp_main__, which are special names used for the module being run as a script, and the same module in a child process, respectively. Dan Constantinescu has given a good answer explaining how to print out the actual process name, if you want that instead.

CodePudding user response:

You can provide a name for the child process by using the name argument. Also you can use the current_process().name to better identify which process is running and to display its name:

import multiprocessing as mp


def child_process():
    print('Hi! My name is', mp.current_process().name)


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

Processes create their own memory space and as indicated in the comment, the prints are from: main process, child process loading the script and then child process executing child_process() function. If you do the same but with threads, you will see only two prints as threads share the same memory space:

import threading


def child_thread():
    print('Hi! My name is', threading.current_thread().name)


print('Hi! My name is', threading.current_thread().name)
if __name__ == '__main__':
    threading.Thread(target=child_thread, name="Child thread").start()
  • Related