父进程可能比子进程早结束,如果父进程要阻塞以等待子进程,可以使用wait或waitpid函数,wait函数只是waitpid函数的简化版。函数原型:
pid_t waitpid (pid_t PID, int *STATUS-PTR, int OPTIONS)
看下面的例子:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
int main()
{
pid_t pid,wpid;
int status,i;
pid=fork();
if(pid<0)
{
printf("failed to create process/n");
exit(1);
}
if(pid==0)//subprocess
{
printf("subprocess,pid=%d/n",getpid());
sleep(5);
exit(0);
}
else
{
printf("parent process,waiting.../n");
wpid=waitpid(pid,&status,0);
i=WEXITSTATUS(status);/*return lower 8 bits of status*/
printf("waiting for subprocess whose pid is %d ,exit status = %d /n",wpid,i);
}
}
运行结果:
yaojun@linux-zv38:~/programs/linuxc> gcc 6.6.c -o 6.6
yaojun@linux-zv38:~/programs/linuxc> 6.6
subprocess,pid=6872
parent process,waiting...
waiting for subprocess whose pid is 6872 ,exit status = 0
详细说明如下:
26.6 Process Completion
=======================
The functions described in this section are used to wait for a child
process to terminate or stop, and determine its status. These functions
are declared in the header file `sys/wait.h'.
-- Function: pid_t waitpid (pid_t PID, int *STATUS-PTR, int OPTIONS)
The `waitpid' function is used to request status information from a
child process whose process ID is PID. Normally, the calling
process is suspended until the child process makes status
information available by terminating.
Other values for the PID argument have special interpretations. A
value of `-1' or `WAIT_ANY' requests status information for any
child process; a value of `0' or `WAIT_MYPGRP' requests
information for any child process in the same process group as the
calling process; and any other negative value - PGID requests
information for any child process whose process group ID is PGID.
If status information for a child process is available
immediately, this function returns immediately without waiting.
If more than one eligible child process has status information
available, one of them is chosen randomly, and its status is
returned immediately. To get the status from the other eligible
child processes, you need to call `waitpid' again.
The OPTIONS argument is a bit mask. Its value should be the
bitwise OR (that is, the `|' operator) of zero or more of the
`WNOHANG' and `WUNTRACED' flags. You can use the `WNOHANG' flag
to indicate that the parent process shouldn't wait; and the
`WUNTRACED' flag to request status information from stopped
processes as well as processes that have terminated.
The status information from the child process is stored in the
object that STATUS-PTR points to, unless STATUS-PTR is a null
pointer.
This function is a cancellation point in multi-threaded programs.
This is a problem if the thread allocates some resources (like
memory, file descriptors, semaphores or whatever) at the time
`waitpid' is called. If the thread gets canceled these resources
stay allocated until the program ends. To avoid this calls to
`waitpid' should be protected using cancellation handlers.
The return value is normally the process ID of the child process
whose status is reported. If there are child processes but none
of them is waiting to be noticed, `waitpid' will block until one
is. However, if the `WNOHANG' option was specified, `waitpid'
will return zero instead of blocking.
If a specific PID to wait for was given to `waitpid', it will
ignore all other children (if any). Therefore if there are
children waiting to be noticed but the child whose PID was
specified is not one of them, `waitpid' will block or return zero
as described above.
A value of `-1' is returned in case of error. The following
`errno' error conditions are defined for this function:
`EINTR'
The function was interrupted by delivery of a signal to the
calling process. *Note Interrupted Primitives::.
`ECHILD'
There are no child processes to wait for, or the specified PID
is not a child of the calling process.
`EINVAL'
An invalid value was provided for the OPTIONS argument.
These symbolic constants are defined as values for the PID argument
to the `waitpid' function.
`WAIT_ANY'
This constant macro (whose value is `-1') specifies that `waitpid'
should return status information about any child process.
`WAIT_MYPGRP'
This constant (with value `0') specifies that `waitpid' should
return status information about any child process in the same
process group as the calling process.
These symbolic constants are defined as flags for the OPTIONS
argument to the `waitpid' function. You can bitwise-OR the flags
together to obtain a value to use as the argument.
`WNOHANG'
This flag specifies that `waitpid' should return immediately
instead of waiting, if there is no child process ready to be
noticed.
`WUNTRACED'
This flag specifies that `waitpid' should report the status of any
child processes that have been stopped as well as those that have
terminated.
-- Function: pid_t wait (int *STATUS-PTR)
This is a simplified version of `waitpid', and is used to wait
until any one child process terminates. The call:
wait (&status)
is exactly equivalent to:
waitpid (-1, &status, 0)
This function is a cancellation point in multi-threaded programs.
This is a problem if the thread allocates some resources (like
memory, file descriptors, semaphores or whatever) at the time
`wait' is called. If the thread gets canceled these resources
stay allocated until the program ends. To avoid this calls to
`wait' should be protected using cancellation handlers.
-- Function: pid_t wait4 (pid_t PID, int *STATUS-PTR, int OPTIONS,
struct rusage *USAGE)
If USAGE is a null pointer, `wait4' is equivalent to `waitpid
(PID, STATUS-PTR, OPTIONS)'.
If USAGE is not null, `wait4' stores usage figures for the child
process in `*RUSAGE' (but only if the child has terminated, not if
it has stopped). *Note Resource Usage::.
This function is a BSD extension.
Here's an example of how to use `waitpid' to get the status from all
child processes that have terminated, without ever waiting. This
function is designed to be a handler for `SIGCHLD', the signal that
indicates that at least one child process has terminated.
void
sigchld_handler (int signum)
{
int pid, status, serrno;
serrno = errno;
while (1)
{
pid = waitpid (WAIT_ANY, &status, WNOHANG);
if (pid < 0)
{
perror ("waitpid");
break;
}
if (pid == 0)
break;
notice_termination (pid, status);
}
errno = serrno;
}
File: libc.info, Node: Process Completion Status, Next: BSD Wait Functions, Prev: Process Completion, Up: Processes
26.7 Process Completion Status
==============================
If the exit status value (*note Program Termination::) of the child
process is zero, then the status value reported by `waitpid' or `wait'
is also zero. You can test for other kinds of information encoded in
the returned status value using the following macros. These macros are
defined in the header file `sys/wait.h'.
-- Macro: int WIFEXITED (int STATUS)
This macro returns a nonzero value if the child process terminated
normally with `exit' or `_exit'.
-- Macro: int WEXITSTATUS (int STATUS)
If `WIFEXITED' is true of STATUS, this macro returns the low-order
8 bits of the exit status value from the child process. *Note
Exit Status::.
-- Macro: int WIFSIGNALED (int STATUS)
This macro returns a nonzero value if the child process terminated
because it received a signal that was not handled. *Note Signal
Handling::.
-- Macro: int WTERMSIG (int STATUS)
If `WIFSIGNALED' is true of STATUS, this macro returns the signal
number of the signal that terminated the child process.
-- Macro: int WCOREDUMP (int STATUS)
This macro returns a nonzero value if the child process terminated
and produced a core dump.
-- Macro: int WIFSTOPPED (int STATUS)
This macro returns a nonzero value if the child process is stopped.
-- Macro: int WSTOPSIG (int STATUS)
If `WIFSTOPPED' is true of STATUS, this macro returns the signal
number of the signal that caused the child process to stop.