—进程控制 下篇

Posted the_scent_of_th_soul

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了—进程控制 下篇相关的知识,希望对你有一定的参考价值。

我们知道,父子进程终止的先后顺序不同会产生不同的结果,下面,我简单说明一下几个容易混淆的概念。
1.孤儿进程:如果一个子进程的父进程先于子进程结束,那么子进程就会成为孤儿进程,它会由init进程收养,成为init进程的子进程。
2.僵尸进程:当子进程先于父进程终止,而父进程又没有调用wait函数等待子进程结束,子进程就会进入僵死状态,并且会一直保持下去,除非系统重启。此时,该子进程就是一个僵尸进程。
如果子进程先父进程退出,并且父进程调用了wait或者waitpid函数,那么子进程既不会变成孤儿进程, 也不会变成僵尸进程。
这两个函数的声明如下:

pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
/*statloc所指向的变量存放子进程的退出码,pid指明要等待的子进程的PID
options 参数允许用户改变waitpid的行为*/

下面是等待进程的处理实例:

int main(void)

    pid_t pid;
    char *msg;
    int k;
    int exit_code;

    printf("study how to get exit code\\n");
    pid=fork();
    switch(pid)
        case 0:
            msg="child process is running";
            k=5;
            exit_code=37;
            break;
        case -1:
            perror("process creation failed\\n");
            exit(-1);
        default:
            exit_code=0;
            break;
    
    if(pid != 0)
        int stat_val;
        pid_t child_pid;
        child_pid=wait(&stat_val);

        printf("child process has exited ,pid=%d\\n", child_pid);
        if(WIFEXITED(stat_val))
           printf("child exited with code:%d\\n", WEXITSTATUS(stat_val));
        
        else
            printf("child exit abnormally\\n");
        
    
    else
        while(k-- >0)
            puts(msg);
            sleep(1);
        
    
    exit(exit_code);
}

父进程调用wait函数后被挂起等待,暂停执行,直到到它的一个子进程结束为止。wait等待第一个终止的子进程。而waitpid则可以指定等待特定的子进程。输入命令 ps aux 可以看到等待时的父进程状态为S.
下面说明本章的难点:创建守护进程
1.概念:守护进程是指后台运行的、没有控制终端与之相连的进程。
控制终端:在linux中,每一个系统与用户进行交流的界面称为终端,每一个从终端开始运行的进程都会依附与这个终端,这个终端就叫做这些进程的控制终端,当控制终端被关闭时,相应的进程都会自动关闭。
守护进程没有控制终端与之相连,也就是说,守护进程突破控制终端的限制,它从被执行开始运转,直到整个系统关闭时才退出。
2.编写守护进程的步骤:

让进程在后台执行   /*调用fork产生一个子进程,然后使父进程退出*/
调用setsid创建一个新对话期 /*setsid调用成功后,进程成为新的会话组长和进程组长*/
禁止进程新打开终端/*再次通过fork创建新的子进程,使调用fork的进程退出(不是组长)*/
关闭不再需要的文件描述符/*先得到最高文件描述符值然后关闭从0到最高描述符值的文件*/
将当前目录更改为根目录
将文件创建时使用的屏蔽字设置为0/*避免从父进程继承的拒绝某些许可权,使用umask(0)*/
处理SIGCHLD  /*这一步不是必须的,但在服务器进程往往在请求到来时生成子进程处理请求,将SIGCHLD信号的操作设为SIG_IGN,使得子进程结束时不会产生僵尸进程。*/

以上是关于—进程控制 下篇的主要内容,如果未能解决你的问题,请参考以下文章

守护进程

泰涨知识 | 从0到1了解微服务架构设计及使用(下篇)

setsid()

会话 控制终端 setsid

Unix高级编程之进程控制

Linux守护进程