简介
wait, waitpid 等待进程状态发送变化
用法
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);
All of these system calls are used to wait for state changes in a child of the calling process, and obtain information about the child whose state has changed. A state change is
considered to be: the child terminated; the child was stopped by a signal; or the child was resumed by a signal. In the case of a terminated child, performing a wait allows the
system to release the resources associated with the child; if a wait is not performed, then the terminated child remains in a “zombie” state
等待被调用的子进程状态发生变化,这些状态包括:进程终止、收到信号停止,恢复。在进程终止的情况下执行wait允许系统释放与子进程关联的资源,如果没有执行wait则终止的子进程会处于僵尸状态。
PS:父进程死了,子进程活着。这时候子进程会成为精灵进程,一般后台的常驻都是这种实现。
:子进程死了,父进程活着,执行wait了释放子进程资源,没有执行资源不释放成为僵尸进程。
详细用法
pid:
< -1 等待所有进程组id等于pid绝对值的子进程。
-1 等待所有的子进程。
0 等待所有的进组id等于被调进程组id的子进程。
> 0 等待进程id等于pid的子进程。
option:
0
WNOHANG 非阻塞,没有进程退出也立即返回。
WUNTRACED 如果一个子进程暂停函数返回(无法被ptrace跟踪),即使没开此选项也会返回的。
WCONTINUED 如果一个暂停的子进程通过SIGCONT信号恢复,函数也返回。
status:
If status is not NULL, wait() and waitpid() store status information in the int to which it points. This integer can be inspected with the following macros.
WIFEXITED(status):正常结束返回true,exit(返回值),或者主函数return。
WEXITSTATUS(status):获取返回码,只有在WIFEXITED(status)为true情况下才使用。
WIFSIGNALED(status):进程被信号终止返回true。
WTERMSIG(status):获取终止的信号,只有在WIFSIGNALED(status)为true情况下使用。
WCOREDUMP(status):如果进程产生corefile返回真,只有在WIFSIGNALED(status)为true情况下使用,并且WCOREDUMP宏存在。
WIFSTOPPED(status):如果进程被暂停返回true,在WUNTRACED选项下使用。
WSTOPSIG(status):获得暂停的信号,只有在WIFSTOPPED(status)为true的情况下使用。
WIFCONTINUED(status):如果进程被SIGCONT信号恢复返回true。
return:
wait(): on success, returns the process ID of the terminated child; on error, -1 is returned.
waitpid(): on success, returns the process ID of the child whose state has changed; if WNOHANG was specified and one or more child(ren) specified by pid exist, but have not yet changed state,
then 0 is returned. On error, -1 is returned.
error:
ECHILD:The calling process does not have any unwaited-for children.
EINTR WNOHANG was not set and an unblocked signal or a SIGCHLD was caught.
EINVAL The options argument was invalid.
举个栗子
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
pid_t cpid, w;
int status;
cpid = fork();
if (cpid == -1)
{
perror("fork");
exit(EXIT_FAILURE);
}
if (cpid == 0)
{
printf("Child PID is %ld\n", (long) getpid());
if (argc == 1)
{
pause(); /*Wait for signals*/
}
_exit(atoi(argv[1]));
}
else /* Code executed by parent */
{
do {
w = waitpid(cpid, &status, WUNTRACED | WCONTINUED);
if (w == -1)
{
perror("waitpid");
exit(EXIT_FAILURE);
}
if (WIFEXITED(status))
{
printf("exited, status=%d\n", WEXITSTATUS(status));
}
else if (WIFSIGNALED(status))
{
printf("killed by signal %d\n", WTERMSIG(status));
}
else if (WIFSTOPPED(status))
{
printf("stopped by signal %d\n", WSTOPSIG(status));
}
else if (WIFCONTINUED(status))
{
printf("continued\n");
}
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit(EXIT_SUCCESS);
}
return 0;
}
运行
==>gcc waitpid.c -o ww
==>./ww 0
Child PID is 117208
exited, status=0
==>./ww 10
Child PID is 117221
exited, status=10
==>./ww &
[1] 117236
==>Child PID is 117237
kill -SIGSTOP 117237
stopped by signal 19
==>kill -SIGCONT 117237
continued
==>kill -SIGTERM 117237
==>killed by signal 15
[1]+ Done ./ww