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?
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().
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.
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.
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.
You should use Process.join
instead of os.wait4
.
Process.is_alive
calls waitpid
internally through multiprocessing.forking.Popen.poll
.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)
True
.http://asciinema.org/a/5901
Replace following line:
ret = os.wait4(proc.pid, 0)
with:
proc.join()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With