关于APUE 图8-8 孤儿进程例子

来源:互联网 发布:魔女的条件知乎 编辑:程序博客网 时间:2024/05/16 07:46
#include "apue.h"//自定义重要头文件#include <dirent.h>//目录读取函数#include "myerror.h"//定义自定义出错打印函数#include <sys/wait.h>//进程等待处理#include <errno.h>//出错处理#include <signal.h>//信号处理#include <fcntl.h>//文件IO操作头文件#include <unistd.h>//Symbolic Constants mode_t#include <sys/stat.h>#include <limits.h>#include "pathalloc.h"void pr_exit(int status){    if( WIFEXITED(status) )//子进程正常终止,返回真.        printf("normal termination , exit status = %d\n",WEXITSTATUS(status));    else if(WIFSIGNALED(status))//子进程异常终止,则返回真.可返回异常信号编号        printf("abnornal termination , singal number = %d%s\n",               WTERMSIG(status),               (WCOREDUMP(status) ? " (core file genarate)" : "") );    else if(WIFSTOPPED(status))//子进程暂停,则返回真.        printf("chlid stopped , signal number = %d\n",WSTOPSIG(status));/*以上所有状态,都储存在int类型变量里面,通过位掩码的方式,存储不同的信息.这是一种很好的小技巧.*/}int main(void){    pid_t pid;    int status;    if( (pid = fork()) < 0 )        err_sys("fork error");    else if(pid == 0){//第一次fork产生子进程child1        if( (pid = fork()) < 0)//child1 fork 产生child2            err_sys("fork error");        else if(pid > 0)//在这里直接退出child1,让child2成为无父进程(其父进程退出了)            exit(0);        sleep(2);//这里就child2进程里面执行,虽然child1里面有这个段代码,但是提前退出了.并且应用了用时拷贝技术        //这里确保exit(0)已经执行完毕        printf("second child , parent pid = %ld\n" , (long)getppid());//这里child2成为孤儿进程,自动被init进程收养        exit(0);//让僵死进程休眠2秒后,退出.    }    sleep(4);//这段代码肯定是在父进程里面执行,因为前面有exit根本到不了这一步.    if( waitpid(pid , &status , 0) != pid)//最大父进程等待child1返回.        err_sys("waitpid error");    pr_exit(status);//child1正常退出时候,主父进程打印消息. 然后再是child2进程打印消息    exit(0);}

ubuntu下运行结果:
second child , parent pid = 1671
normal termination , exit status = 0
可以看出孤儿进程并没有被Init(pid=1)的进程接管。

通过 ps -e指令可以看出upstart的pid=1671
1671 ? 00:00:00 upstart
可知孤儿进程被upstart收养,这是桌面程序进程,当有图形界面的时候,就是这个收养。
可以通过ctrl+alt+F1切换到终端界面,继续执行,正确显示。
这里写图片描述

原创粉丝点击