2.7进程退出、孤儿进程、僵尸进程

目录

1.进程退出

2.孤儿进程

3.僵尸进程


1.进程退出

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

#include <unistd.h>
void _exit(int status);
    status参数:是进程退出时的一个状态信息。父进程回收子进程资源的时候可以获取到。

测试exit函数的程序:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    printf("hello\n");   //有\n
    printf("world");     //无\n
    exit(0);
}

运行结果:

测试_exit函数的程序:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>

int main()
{
    printf("hello\n");   //有\n
    printf("world");     //无\n
    _exit(0);
}

运行结果:

为什么两个输出结果有差别呢?

第一个printf语句带有“\n”,会刷新缓冲区。所以两个程序都输出了hello。

第二个printf语句没有“\n”,从第一个图可知exit函数会刷新缓冲区,_exit函数不会刷新缓冲区,所以第一个程序还会输出world,而第二个程序没有。


2.孤儿进程

程序:

#include <unistd.h>
#include <stdio.h>

int main()
{
    pid_t pid=fork();
    if(pid>0)
    {
        printf("I am a parent process! pid=%d ppid=%d\n",getpid(),getppid());
    }
    else if(pid==0)
    {
        sleep(1);
        printf("I am a child process! pid=%d ppid=%d\n",getpid(),getppid());
    }
    for(int i=0;i<3;i++)
    {
        printf("i=%d pid=%d\n",i,pid);
    }
    return 0;
}

运行结果:

当在终端中执行可执行程序中,会默认切换到该程序执行,这也就是为什么终端中会显示程序中输出的内容。

其中,程序中的父进程的父进程的id 12145为当前终端,可以进行验证:

因为终端是程序中父进程的父进程,所以,终端知道程序中父进程什么时候运行结束,在程序中父进程运行结束之后又切换回终端,所以会显示上上个图中里面红框圈起来的部分。但是终端不知道父进程还有没有运行结束的子进程,所以后面会接着显示程序中子进程的内容。为什么子进程输出的内容也会显示在当前终端呢?因为fork后,子进程和父进程的文件描述符表是一样的(读时共享),代表同一个终端。

孤儿进程会由进程ID为1的init进程收养,由init完成孤儿进程的资源释放工作。孤儿进程是没有危害的。


3.僵尸进程

程序:

#include <unistd.h>
#include <stdio.h>

int main()
{
    pid_t pid=fork();
    if(pid>0)
    {
        while(1)
        {
            printf("I am a parent process! pid=%d ppid=%d\n",getpid(),getppid());
            sleep(5);
        } 
    }
    else if(pid==0)
    {
        printf("I am a child process! pid=%d ppid=%d\n",getpid(),getppid());
    }
    for(int i=0;i<3;i++)
    {
        printf("i=%d pid=%d\n",i,getpid());
    }
    return 0;
}

运行结果:

用ps aux查看进程信息,如下图:

从图中可以看出,子进程12216为僵尸进程。因为子进程已经运行结束了,父进程没有对子进程的内核区数据进行回收,且父进程一直在运行。僵尸进程一直占用系统资源,所以要想办法解决。

解决办法之一:

让父进程结束运行:

因为父进程结束后,子进程(即僵尸进程)的父进程会变为init进程,init进程会对僵尸进程的资源进行回收。

实际上,有时候程序要一直运行,不能用ctrl+c将其杀死。

解决办法之二:

父进程中调用wait函数或waitpid函数对子进程的资源进行回收。这种方法在后面讲。


参考:牛客网 C++高薪求职项目《Linux高并发服务器开发》2.7进程退出、孤儿进程、僵尸进程

专属优惠链接:

https://www.nowcoder.com/courses/cover/live/504?coupon=AvTPnSG

猜你喜欢

转载自blog.csdn.net/m0_38062470/article/details/113797732