Reading the documentation on the daemon attribute for the multiprocessing module, I got the idea that when any process exits, their daemon threads would be terminated…
However, in the small programme below, the ‘grand’-child process does not get terminated, and is allowed to print “Finishing Process…”.
Why is that?
import multiprocessing as mp, time
def pid_task(sec: int):
print(f"Running Process:{mp.current_process().name}")
time.sleep(sec)
print(f"Finishing Process:{mp.current_process().name}")
def create_child(sec):
child = mp.Process(target=pid_task, args=[sec], daemon=True)
child.start()
pid_task(sec)
p1 = mp.Process(target=create_child, args=[5])
p1.start()
pid_task(1)
print("Terminating Process-1 and MainProcess")
p1.terminate()
print("Terminated p1 and terminating MainProcess")
Thank you for your information.
However, I think the point of my observation was something else…
In your code, when we do `p1.join()`, we are blocking the main thread until the child process p1 is finished. This is not what I wanted.
I wanted to terminate this child, and see what happens to its daemon subprocesses.
My point was that the information on the official documentation of daemon threads being terminated when the parent process exits does not seem to be valid in this case. But now, as I write this I see that I was terminating the process… Termination is not the same as allowing a process to exit, even with a non-zero exit.
For threads they are automatically terminated by the OS on exit and the daemon flag tells python to not try to join them on program exit.
Processes aren’t terminated by the OS automatically so the daemon flag instead relies on a python-level atexit handler that keeps track of all daemon processes and calls terminate before joining them.
When a python process is exited in a non-standard way such as by SIGTERM, SIGKILL or calling os._exit() those hooks never run and those guarantees can’t hold.