(1)正常退出
(2)异常退出
检查wait和waitpid所返回的终止状态的宏
宏 | 说明 |
---|---|
WIFEXITED(status) | 若为正常终止子进程返回的状态,则为真。对于这种情况可执行WEXITSTATUS(status),取子进程传送给exit、_exit或_Exit参数的低8位 |
WIFSIGNALED(status) | 若为异常终止子进程返回的状态,则为真(接到一个不捕捉的信号)。对于这种情况,可执行WTERMSIG (status),取使子进程终止的信号编号。另外,有些实现(非Single UNIX Specification)定义宏WCOREDUMP (staus),若已产生终止进程的core文件,则它返回真 |
WIFSTOPPED(status) | 若为当前暂停子进程的返回的状态,则为真。对于这种情况,可执行WSTOPSIG(status),取使子进程暂停的信号编号 |
WIFCONTINUED(status) | 若在作业控制暂停后已经继续的子进程返回了状态,则为真。(POSIX.1的XSI扩展,仅用于waitpid.) |
(3)父进程等待子进程退出
pid_t wait(int *status);
解析子进程返回的状态码
status是一个整形数指针
非空:子进程退出状态放在它所指向的地址中
空: 不关心退出状态
子进程状态不被收集会变成僵尸进程
僵尸进程:当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源。
怎么查看僵尸进程:利用命令ps,可以看到有父进程ID为1的进程是孤儿进程;s(state)状态为Z的是僵尸进程。
注意:孤儿进程(orphan process)是尚未终止但已停止(相当于前台挂起)的进程,但其父进程已经终止,由init收养;而僵尸进程则是已终止的进程,其父进程不一定终止。
status为NULL的代码示例
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid=fork();int cnt;if(pid>0){while(1){wait(NULL);printf("this is father print,pid=%d\n",getpid());sleep(1);printf("cnt=%d\n",cnt);}}else if(pid==0){while(1){printf("this is child print,pid=%d\n",getpid());sleep(1);cnt++;if(cnt==5){exit(-1);}}}return 0;
}
status不为空的代码示例
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid=fork();int status=10;int cnt;if(pid>0){while(1){wait(&status);printf("child quit,child status=%d\n",WEXITSTATUS(status));printf("this is father print,pid=%d\n",getpid());sleep(1);printf("cnt=%d\n",cnt);}}else if(pid==0){while(1){printf("this is child print,pid=%d\n",getpid());sleep(1);cnt++;if(cnt==5){exit(3);}}}return 0;
}
waitpid函数
pid_t waitpid(pid_t pid, int *status, int options);
对于waitpid函数中的pid参数的作用解释如下:
pid==-1 等待任意子进程,就这一方面而言,wait与waitpid等效。
pid>0 等待其进程ID与pid相等的子进程。
pid==0 等待其组ID等于调用进程组ID的任一子进程
pid<-1 等待其组ID等于pid绝对值的任一子进程
waitpid的options常量
常量 | 说明 |
---|---|
WCONTINUED | 若实现支持作业控制,那么由pid指定的任一子进程在暂停后已经继续,但其状态尚未报告,则返回其状态(POSIX.1的XSI扩展)。 |
WNOHANG(常用,不挂起,不堵塞) | 如果pid指定的子进程没有结束,则waitpid()函数立即返回0,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号。 |
WUNTRACED | 若某实现支持作业控制,而由pid指定的任一子进程已处于暂停状态,并且其状态自暂停以来还未报告过,则返回其状态。WIFSTOPPED宏确定返回值是否对应于一个暂停子进程。如果子进程进入暂停状态,则马上返回。 |
如果不想使用这些选项,则可以把这个参数设为0。
如果像这样调用waitpid函数:waitpid(-1, status, 0),这此时waitpid()函数就完全退化成了wait()函数。
代码示例
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main()
{pid_t pid;pid=fork();int status;int cnt;if(pid>0){while(1){waitpid(pid,&status,WNOHANG);printf("child quit,child status=%d\n",WEXITSTATUS(status));printf("this is father print,pid=%d\n",getpid());sleep(1);printf("cnt=%d\n",cnt);}}else if(pid==0){while(1){printf("this is child print,pid=%d\n",getpid());sleep(1);cnt++;if(cnt==5){exit(3);}}}return 0;
}