system函数,回收进程资源 ,僵尸进程和孤儿进程(进程控制)【linux】(zm)

system函数

我们已经实现了通过fork函数创建一个子进程然后通过execve函数来实现子进程代码的加载从而让子进程运行另一个程序。

system函数是对于fork函数和execve函数的封装,调用时会自动创建子进程空间,并且把新程序的代码加载到子进程中运行起来。

system函数
函数原型:
#include <stdio.h>
int system(const char * command);

功能:创建子进程并且加载新程序到子进程空运行起来。
参数:新程序的路径名和文件名

代码演示:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    system("ls");
    return 0;
}

运行结果为:
在这里插入图片描述上面进程赋值的新进程的代码就是ls命令。
在这里插入图片描述

我们可以看到ls在bin这个目录下面。

在这里插入图片描述

这个路径在环境变量当中。所以上面代码不需要外加路径。

那么我们也可以加载我们自己的程序,这个时候就需要加上路径名:
我们在当前文件写入一个main.c文件
main.c

#include <stdio.h>
int main()
{
        printf("this is new process\n");
        return 0;
}

生成可执行文件main
在这里插入图片描述

然后通过system函数加载main函数:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
    system("./main");
    return 0;
}

运行结果为:
在这里插入图片描述

回收进程资源

进程运行终止之后,不管进程是正常终止还是异常终止,必须回收进程所占用的资源。

为什么要回收进程资源?

1:程序代码在内存中动态运行起来之后才有了进程,既然进程结束了,就需要将代码占用的内存空间释放出了。
2:OS为了管理进程,为每一个进程在内从中开辟了一个task_struct 结构体变量,进程结束了,这个结构体所占用的内存空间也需要被释放。
3:进程在运行的过程中也会占用其他资源,我们都要进行释放。

由父进程来回收进程空间,父进程运行结束时,会释放子进程资源。

僵尸进程和孤儿进程

子进程终止,但是父进程还在运行,父进程没有回收子进程资源之前,子进程就是僵尸进程。

孤儿进程:
子进程还在运行,但是父进程终止了,子进程就是孤儿进程

为了能够回收孤儿进程终止后的资源,孤儿进程会被托管到PID为1的init进程,当被托管的子进程终止时,init会立即主动回收孤儿进程的进程资源,回收资源很快,所以孤儿进程没有变成僵尸进程。

代码演示:僵尸进程

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    pid_t ret = 0;
    ret = fork();
    if(ret>0)
    {
        while(1);
    }
    else if(ret == 0)
    {
            
    }
    return 0;

}

运行结果为:
在这里插入图片描述

我们把与所有终端相关的的进程进行显示:

在这里插入图片描述

我们可以看到最前面有不同大写的字母:

R代表正在运行
S代表处于休眠状态
Z代表僵尸进程,进程运行完等待被回收资源。

我们可以看到父进程PID为10731的进程前面时R,R代表正在运行。
子进程PID为11648的进程前面时Z表示的是僵尸进程。

代码演示:孤儿进程

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
        pid_t ret = 0;
        ret = fork();
        if(ret>0)
        {

        }
        else if(ret == 0)
        {
                        while(1);
        }
        return 0;

}

运行结果为:
在这里插入图片描述

我们可以看到在执行之后退出了,这个时候父进程结束了,就把终端控制权返回给shell程序,这个时候子进程一直在执行。我们进行查看:

在这里插入图片描述此时a.out是子进程并且正在运行,就是孤儿进程。

发布了163 篇原创文章 · 获赞 94 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_43648751/article/details/104508458