The processes started with multiprocessing are remaining in the run queue, even after their target function returned.
This problem seams to be specific to linux, on windows everything matches my expectations.
Consider this program:
import multiprocessing
def hello_word():
time.sleep(5)
print("Hi mom, im in another process!")
if __name__ == '__main__':
multiprocessing.freeze_support()
time.sleep(3)
p=multiprocessing.Process(target=hello_word)
p.start()
time.sleep(15)
print("Asking is_alive()")
print(p.is_alive())
time.sleep(5)
The output is:
Hi mom, im in another process!
Asking is_alive()
False
As it is expected. But if you using an external program to monitor your processes (like top, htop or psgrep) you can see that the childprocess is living until the exact moment you are calling it's is_alive method from the parent, not exits after 'hi mom...' printed. If you never call is_alive() on the process it is living until the parent proc exits.
On windows however everything works as it expected the process only listed on the taskmgr until hi mom printed.
Am I misunderstanding something? How to get rid of the child process without calling it's is_alive?
CodePudding user response:
This happens because calling is_alive()
automatically joins the the processes if they have completed. In general, after the process is completed, you must join (or terminate) the process otherwise it won't release the resources in use and continue to exist until you do join it. From the documentation:
On Unix when a process finishes but has not been joined it becomes a zombie. There should never be very many because each time a new process starts (or active_children() is called) all completed processes which have not yet been joined will be joined. Also calling a finished process’s Process.is_alive will join the process. Even so it is probably good practice to explicitly join all the processes that you start.