运维开发网

浅谈Linux下僵尸进程、孤儿进程以及环境变量

运维开发网 https://www.qedev.com 2021-02-13 12:16 出处:51CTO 作者:星辰之洛
僵尸进程1.原理:子进程先于父进程退出,父进程来不及回收子进程的资源,导致子进程变成僵尸进程,而子进程所对应的task_struct还在内核当中,双向链表管理着。对于子进程而言,程序是已经退出了,并不能执行任何用户的代码了;子进程的状态会变为Z状态;”刀枪不入“2.产生僵尸进程之后,僵尸进程对应的状态是Z,并且使用kill命令或者强杀命令kill-9,都结束不了僵尸进程3.僵尸进程的危害:产生僵尸

僵尸进程

1.原理:

子进程先于父进程退出,父进程来不及回收子进程的资源,导致子进程变成僵尸进程,而子进程所对应的task_struct还在内核当中,双向链表管理着。对于子进程而言,程序是已经退出了,并不能执行任何用户的代码了;子进程的状态会变为Z状态;”刀枪不入“

2.产生僵尸进程之后,僵尸进程对应的状态是Z,并且使用kill命令或者强杀命令 kill -9 ,都结束不了僵尸进程

3.僵尸进程的危害:

产生僵尸进程后,僵尸进程是不能被强杀杀死的,意味着在操作系统内核双向链表还维护着僵尸进程的task_struct。内核维护这样的结构体是要耗费内存的,程序员还结束不了僵尸进程,所以操作系统内存泄露了。

4.如何预防僵尸进程的产生:

  1. 子进程不要先于父进程退出 (不可取
  2. 进程等待(后面介绍) (可取,优雅的预防
  3. 可以将父进程kill掉,然后僵尸进程就变成了孤儿进程,进而僵尸进程被1号进程领养,1号进程回收僵尸进程的资源。 (杀敌一千,自损八百,不可取)

来段代码测试一下

//测试代码
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main()
{
    printf("hello\n");
    pid_t ret = fork();
    if(ret < 0)
    {
        perror("fork error");
        return 0;
    }
    else if(ret == 0)
    {
        //child
        printf("i am child, pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(5);
    }
    else
    {
        //father
        while(1)
        {
            printf("i am father, pid=%d, ppid=%d\n", getpid(), getppid());
            sleep(1);
         }
     }
     return 0;
}

在另一个终端输入ps aux | head -1; ps aux | grep testZ | grep -v grep进行监控,5秒后进程进入僵尸状态

浅谈Linux下僵尸进程、孤儿进程以及环境变量

可验证kill -9也无法强杀僵尸进程

浅谈Linux下僵尸进程、孤儿进程以及环境变量

可以将父进程kill掉,再查看僵尸进程状态,可见其已被操作系统回收

浅谈Linux下僵尸进程、孤儿进程以及环境变量

孤儿进程

  • 1.原理:

父进程先于子进程退出,子进程会被1号进程所领养,1好进程被称为init进程。1号进程会在子进程退出的时候回收子进程的退出信息,防止子进程变为僵尸进程。

  • 2.现象
//测试代码
#include <stdio.h>                                                        
#include <unistd.h>
#include <stdlib.h>

int main()
{
    printf("hello\n");
    pid_t ret = fork();
    if(ret < 0)
    {
        perror("fork error");
        return 0;
    }
    else if(ret == 0)
    {
        //child
        printf("i am child, pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(10);
    }
    else
    {
        //father
        printf("i am father, pid=%d, ppid=%d\n", getpid(), getppid());
        sleep(5);
    }

    return 0;
}

在终端监控下,可以看到子进程的ppid变为1

浅谈Linux下僵尸进程、孤儿进程以及环境变量

  • 3.注意:孤儿进程不是一种进程状态!而是一种进程种类的名称

环境变量

1.概念:环境变量是用来定义系统运行环境的一些参数的

问题:为什么ls程序可以在任意目录下运行,而我们编译出来的代码,只能在当前编译目录下运行?

2.常见环境变量

HOME:保存用户家目录的环境变量

SHELL:保存当前使用的命令行解释器

PATH:保存可执行程序路径的环境变量

LD_LIBRARY_PATH:程序运行时依赖的库文件的搜索路径的环境变量

3.查看环境变量:echo $环境变量名称

4.新增环境变量的值

用export去更改或增加环境变量的值

万能公式:export [环境变量名称] = $[环境变量名称] : [新增加环境变量的值]

eg: export PATH = $PATH:/home/test

注意:在命令行当中使用export是临时生效的做法,只在当前终端内有效,当前终端关闭后,重新打开就没有之前设置的值了。

永久生效:将环境变量的值写到下面的文件中

  1. 普通用户:~/.bashrc 或者~/.bash_profile
  2. 系统环境变量设置:(普通用户的环境变量不要往系统里添加)

    /etc/bashrc

添加完成后使用source命令重新加载文件

source:告诉操作系统内核重新加载某一文件

用法:source 环境变量文件

和环境变量相关的命令

  1. echo: 显示某个环境变量值
  2. export: 设置一个新的环境变量
  3. env: 显示所有环境变量
  4. unset: 清除环境变量
  5. set: 显示本地定义的shell变量和环境变量

来看个例子进行测试

//测试代码
#include <stdio.h>

int main()
{
    printf("hello world\n");
    return 0;
}

执行程序可看到如下结果

浅谈Linux下僵尸进程、孤儿进程以及环境变量

0

精彩评论

暂无评论...
验证码 换一张
取 消