进程的退出方式以及僵尸进程和孤儿进程

(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值