Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiprocessing.Process.is_alive() returns True although process has finished, why?

I use multiprocess.Process to create a child process and then call os.wait4 until child exists. When the actual child process finishes, multiprocess.Process.is_alive() still returns True. That's contradicting. Why?

Code:

from multiprocessing import Process
import os, sys

proc = Process(target=os.system, args= ("sleep 2", ))
proc.start()

print "is_alive()", proc.is_alive()
ret = os.wait4(proc.pid, 0)
procPid, procStatus, procRes = ret
print "wait4 = ", ret

## Puzzled!
print "----Puzzled below----"
print "is_alive()", proc.is_alive()
if os.WIFEXITED(procStatus):
    print "exit with status", os.WEXITSTATUS(procStatus)
print "is_alive()", proc.is_alive()
sys.exit(1)

Output:

is_alive() True
wait4 =  (11137, 0, resource.struct_rusage(ru_utime=0.0028959999999999997, ru_stime=0.003189, ru_maxrss=1363968, ru_ixrss=0, ru_idrss=0, ru_isrss=0, ru_minflt=818, ru_majflt=0, ru_nswap=0, ru_inblock=0, ru_oublock=0, ru_msgsnd=0, ru_msgrcv=0, ru_nsignals=0, ru_nvcsw=1, ru_nivcsw=9))
----Puzzled below----
is_alive() True
exit with status 0
is_alive() True

My question is about the last three output lines. Why is_alive() return True when the actual process is finished. How can that happen?

like image 588
zhanxw Avatar asked Oct 14 '13 04:10

zhanxw


People also ask

What does multiprocessing process return?

We can return a variable from a process using the multiprocessing. Queue class. A queue is a data structure on which items can be added by a call to put() and from which items can be retrieved by a call to get().

How does multiprocessing process work?

multiprocessing is a package that supports spawning processes using an API similar to the threading module. The multiprocessing package offers both local and remote concurrency, effectively side-stepping the Global Interpreter Lock by using subprocesses instead of threads.

How do you stop a multiprocessing process?

A process can be killed by calling the Process. kill() function. The call will only terminate the target process, not child processes. The method is called on the multiprocessing.

What is process join () in Python?

Python multiprocessing join The join method blocks the execution of the main process until the process whose join method is called terminates. Without the join method, the main process won't wait until the process gets terminated.


1 Answers

You should use Process.join instead of os.wait4.

  • Process.is_alive calls waitpid internally through multiprocessing.forking.Popen.poll.
  • If you call os.wait4, waitpid raises os.error which cause the poll() to return None. (http://hg.python.org/cpython/file/c167ab1c49c9/Lib/multiprocessing/forking.py#l141)
  • is_alive() use that return value to determine whether the process is alive. (http://hg.python.org/cpython/file/c167ab1c49c9/Lib/multiprocessing/process.py#l159)
    • => return True.

http://asciinema.org/a/5901


Replace following line:

ret = os.wait4(proc.pid, 0)

with:

proc.join()
like image 94
falsetru Avatar answered Oct 14 '22 20:10

falsetru