#!/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:
I am confused about
- Why the child process name is mp_main?
- 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()