基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程

这篇具有很好参考价值的文章主要介绍了基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

01 / 进程退出

基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程,linux,服务器,运维

exit.c

/*
    #include <stdlib.h>
    void exit(int status);

    #include <unistd.h>
    void _exit(int status);

    status参数:是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main() {

    printf("hello\n");
    printf("world");

    // exit(0);
    _exit(0);
    
    return 0;
}

02 / 孤儿进程

◼ 父进程运行结束,但子进程还在运行(未运行结束),这样的子进程就称为孤儿进程 (Orphan Process)。

◼ 每当出现一个孤儿进程的时候,内核就把孤儿进程的父进程设置为 init ,而 init 进程会循环地 wait() 它的已经退出的子进程。这样,当一个孤儿进程凄凉地结束 了其生命周期的时候,init 进程就会代表党和政府出面处理它的一切善后工作。

◼ 因此孤儿进程并不会有什么危害。

orphan.c

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main() {

    // 创建子进程
    pid_t pid = fork();

    // 判断是父进程还是子进程
    if(pid > 0) {

        printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());

    } else if(pid == 0) {
        sleep(1);
        // 当前是子进程
        printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());
       
    }

    // for循环
    for(int i = 0; i < 3; i++) {
        printf("i : %d , pid : %d\n", i , getpid());
    }

    return 0;
}

03 / 僵尸进程

◼ 每个进程结束之后, 都会释放自己地址空间中的用户区数据,内核区的 PCB 没有办法 自己释放掉,需要父进程去释放。

◼ 进程终止时,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成僵尸 (Zombie)进程。

◼ 僵尸进程不能被 kill -9 杀死,这样就会导致一个问题,如果父进程不调用 wait() 或 waitpid() 的话,那么保留的那段信息就不会释放,其进程号就会一直被占用, 但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进 程号而导致系统不能产生新的进程,此即为僵尸进程的危害,应当避免。

zombie.c

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main() {

    // 创建子进程
    pid_t pid = fork();

    // 判断是父进程还是子进程
    if(pid > 0) {
        while(1) {
            printf("i am parent process, pid : %d, ppid : %d\n", getpid(), getppid());
            sleep(1);
        }

    } else if(pid == 0) {
        // 当前是子进程
        printf("i am child process, pid : %d, ppid : %d\n", getpid(),getppid());
       
    }

    // for循环
    for(int i = 0; i < 3; i++) {
        printf("i : %d , pid : %d\n", i , getpid());
    }

    return 0;
}

开启 另一个终端,ps aux查看如下信息,Z+表示是僵尸进程 

基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程,linux,服务器,运维

kill -9 14860 ,变成僵尸进程(Z+),不能被kill -9杀死

基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程,linux,服务器,运维

 04 / 进程回收

◼ 在每个进程退出的时候,内核释放该进程所有的资源、包括打开的文件、占用的内 存等。但是仍然为其保留一定的信息,这些信息主要主要指进程控制块PCB的信息 (包括进程号、退出状态、运行时间等)。

◼ 父进程可以通过调用wait或waitpid得到它的退出状态同时彻底清除掉这个进程。

◼ wait() 和 waitpid() 函数的功能一样,区别在于,wait() 函数会阻塞, waitpid() 可以设置不阻塞,waitpid() 还可以指定等待哪个子进程结束。

◼ 注意:一次wait或waitpid调用只能清理一个子进程,清理多个子进程应使用循环。

05 / 退出信息相关宏函数

◼ WIFEXITED(status) 非0,进程正常退出

◼ WEXITSTATUS(status) 如果上宏为真,获取进程退出的状态(exit的参数)

◼ WIFSIGNALED(status) 非0,进程异常终止

◼ WTERMSIG(status) 如果上宏为真,获取使进程终止的信号编号

◼ WIFSTOPPED(status) 非0,进程处于暂停状态

◼ WSTOPSIG(status) 如果上宏为真,获取使进程暂停的信号的编号

◼ WIFCONTINUED(status) 非0,进程暂停后已经继续运行文章来源地址https://www.toymoban.com/news/detail-574993.html

到了这里,关于基于linux下的高并发服务器开发(第二章)- 2.7 进程退出、孤儿进程、僵尸进程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包