How to get return values of a forked process

I

Ian

Hello all,

I need some helped with forking. In my script, I fork a process. I
want to get return values from the child process.

This is the script that does the forking:
for x in (mylist):
pid = os.fork()
if pid:
pidList.append(pid)
else:
os.execv('/usr/bin/python',('/usr/bin/
python',myForkedScript))

for pid in pidList:
childPid, status = os.waitpid(pid,0)
# I think status should be the return value of the forked
process; I would expect status to be a 1 or a 0

myForkedScript has code like this:
if fail:
os._exit(1)
else:
os._exit(os.EX_OK)


Is using os._exit() the correct way to get a return value back to the
main process?

I thought the value 'n', passed in os._exit(n) would be the value I
get returned. In the case of a failure, I get 256 returned rather
than 1.

Thanks for the assistance!
IL
 
I

Ian Kelly

myForkedScript has code like this:
if fail:
os._exit(1)
else:
os._exit(os.EX_OK)

Is using os._exit() the correct way to get a return value back to the
main process?

sys.exit() is the preferred way.
I thought the value 'n', passed in os._exit(n) would be the value I
get returned. In the case of a failure, I get 256 returned rather
than 1.

According to the docs, on Unix:

"""
Wait for completion of a child process, and return a tuple containing
its pid and exit status indication: a 16-bit number, whose low byte is
the signal number that killed the process, and whose high byte is the
exit status (if the signal number is zero); the high bit of the low
byte is set if a core file was produced.
"""

And on Windows:

"""
Wait for completion of a process given by process handle pid, and
return a tuple containing pid, and its exit status shifted left by 8
bits (shifting makes cross-platform use of the function easier).
"""

(256 >> 8) == 1

However, I would advise using the subprocess module for this instead
of the os module (which is just low-level wrappers around system
calls).
 
I

Ian

sys.exit() is the preferred way.


According to the docs, on Unix:

"""
Wait for completion of a child process, and return a tuple containing
its pid and exit status indication: a 16-bit number, whose low byte is
the signal number that killed the process, and whose high byte is the
exit status (if the signal number is zero); the high bit of the low
byte is set if a core file was produced.
"""

And on Windows:

"""
Wait for completion of a process given by process handle pid, and
return a tuple containing pid, and its exit status shifted left by 8
bits (shifting makes cross-platform use of the function easier).
"""

(256 >> 8) == 1

However, I would advise using the subprocess module for this instead
of the os module (which is just low-level wrappers around system
calls).

Where did you find the Unix docs you pasted in? I didn't find it in
the man pages. Thank you. Based on what you say, I will change my
os._exit() to sys.exit().
 
I

Ian Kelly

Where did you find the Unix docs you pasted in?  I didn't find it in
the man pages.  Thank you.  Based on what you say, I will change my
os._exit() to sys.exit().

http://docs.python.org/library/os.html#os.wait
http://docs.python.org/library/os.html#os.waitpid

I don't know what man pages you were looking at, but the Unix system
call does work the same way; to extract the exit status in C you're
supposed to use the WEXITSTATUS(status) macro, which is typically
implemented as ((status >> 8) & 0377). See:

http://linux.die.net/man/2/waitpid
 
C

Chris Torek

"The" correct way, no, but it is "a" correct way (and cheaper than
using a pipe to pickle and unpickle failure, the way the subprocess
module does it, for instance). In any case, you *should* call
os._exit() either directly or indirectly after a successful fork
but a failed exec.

Using sys.exit() after a fork() has other risks (principally,
duplication of pending output when flushing write-mode streams),
which is why os._exit() is provided.
I thought the value 'n', passed in os._exit(n) would be the value I
get returned.  In the case of a failure, I get 256 returned rather
than 1.
According to the docs ... [snip documentation and description]
However, I would advise using the subprocess module for this instead
of the os module (which is just low-level wrappers around system
calls).

Indeed, subprocess gives you convenience, safety, and platform
independence (at least across POSIX-and-Windows) with a relatively
low cost. As long as the cost is low enough (and it probably is)
I agree with this.

Where did you find the Unix docs you pasted in? I didn't find it in
the man pages. Thank you. Based on what you say, I will change my
os._exit() to sys.exit().

Not sure where Ian Kelly's documentation came from, but note that on
Unix, the "os" module also provides os.WIFSIGNALED, os.WTERMSIG,
os.WIFEXITED, and os.WEXITSTATUS for dissecting the "status"
integer returned from the various os.wait* calls.

Again, if you use the subprocess module, you are insulated from
this sort of detail (which, as always, has both advantages and
disadvantages).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top