b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

Linux 僵尸进程造成因素及缓解方法

电脑杂谈  发布时间:2019-08-23 14:10:46  来源:网络整理

linux僵尸程序_linux程序移植到android_linux查看程序端口

Linux 允许进程查询内核以获取其父进程的 PID,或者其任何子进程的执行状况。例如,进程可以建立一个子进程来执行特定的任务,然后读取诸如 wait() 这样的一些库函数检测子进程是否终止。如进程已经中止,那么,它的解除代号将告诉父进程这个任务能否已顺利地完成。

为了顺应这些设计方法,不允许 Linux 内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被中止的进程相关的 wait() 类平台调用时候,才允许这样做。这就是引入僵死状态的缘由:尽管从技术上来说进程已死,但需要保存它的表述符,直到父进程得到通知。

如果一个进程将要中止,但是它的父进程尚未调用 wait() 或 waitpid() 对它进行清除,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程(zombie process)。任何进程在刚中止时都是僵尸进程,正常状况下,僵尸进程都立刻被父进程清理了。

僵尸进程是能否形成的

在UNIX 系统中,一个进程结束了,但是他的父进程没有等待(调用wait / waitpid)他,那么他将变成一个僵尸进程。通过ps命令查看其具有defunct的标识。僵尸进程是一个早已死亡的进程,但在进程表 (processs table)中仍占了一个位置(slot)。

linux程序移植到android_linux查看程序端口_linux僵尸程序

但是如果该进程的父进程将要先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的之后,系统就会扫描当前平台中所运行的所有进程,看看有没有哪个 进程是今天结束的这个进程的子进程,如果是的话linux僵尸程序,就由Init进程来接管他,成为他的父进程,从而保证每个进程就会有一个父进程。而Init进程会自动 wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。

为了观察到僵尸进程,我们自己写一个不正常的程序,父进程 fork 出子进程,子进程中止,而父进程既不终止也不读取 wait 清理子进程:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  int i = 100;
  pid_t pid=fork();
  if(pid < 0)
  {
    perror("fork failed.");
    exit(1);
  }
  if(pid > 0)
  {
    printf("This is the parent process. My PID is %d.
", getpid());
    for(; i > 0; i--)
    {
      sleep(1);
    }
  }
  else if(pid == 0)
  {
    printf("This is the child process. My PID is: %d. My PPID is: %d.
", getpid(), getppid());
  }
  return 0;
}

把里面的代码保存到文件 zomprocdemo.c 文件中,并执行上面的命令编译:

$ gcc zomprocdemo.c -o zomprocdemo

linux僵尸程序_linux查看程序端口_linux程序移植到android

然后运行编译出来的 zomprocdemo 程序:

$ ./zomprocdemo

此时子进程已经退出,但是父进程没有退出也没有通过 wait() 调用处理子进程。我们使用 ps 命令查看进程的状况:

上图红框中的大写字母 "Z" 说明 PID 为 112712 的进程此时进入僵死的状况。

让我们接着往下看!在结束 sleep 后父进程退出。当父进程退出后,子进程会成为孤儿进程,此时它会被一个管理进程收养。在不同的系统中,这个管理进程不太一样,早期一般是 init 进程,Ubuntu 上是 upstart,还有最近的 Systemd。但是它们都完成相同的任务,就是 wiat() 这些孤儿进程,并最后释放它们占用的平台进程表中的资源。这样,这些将要僵死的孤儿进程就彻底的被消灭了。

linux僵尸程序_linux程序移植到android_linux查看程序端口

僵尸进程的弊端

在进程退出的之后linux僵尸程序,内核释放该进程所有的资源,包括开启的文件,占用的存储等。但是显然为其保留一定的信息(包括进程号 PID,退出状态 the termination status of the process,运行时间 the amount of CPU time taken by the process 等)。直到父进程通过 wait / waitpid 来取时才传递。

如果进程不读取 wait / waitpid 的话, 那么保留的那段信息就不会释放,其进程号都会一直被占用,但是平台所能使用的进程号是有限的,如果长期的形成僵死进程,将因为没有可用的进程号而造成平台不能产生新的进程。

如何处理僵尸进程

僵尸进程的形成是因为父进程没有 wait() 子进程。所以如若我们自己写程序的话一定要在父进程中借助 wait() 来防止僵尸进程的形成。

linux查看程序端口_linux僵尸程序_linux程序移植到android

当系统中发生了僵尸进程时,我们是能够借助 kill 命令把它消灭掉的。但是我们可以打败它的父进程,让它成为孤儿进程,并进一步被系统中管理孤儿进程的进程收养并清理。

下面的 demo 中,父进程通过 wait() 等待子进程结束:

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
  pid_t pid;
  pid = fork();
  if (pid < 0)
  {
    perror("fork failed");
    exit(1);
  }
  if (pid == 0) {
    int i;
     for (i = 3; i > 0; i--)
     {
      printf("This is the child
");
      sleep(1);
     }
     // exit with code 3 for test.
    exit(3);
  }
  else
  {
    int stat_val;
    wait(&stat_val);
     if (WIFEXITED(stat_val))
     {
       printf("Child exited with code %d
", WEXITSTATUS(stat_val));
     }      
  }
  return 0;
}

demo 中父进程不仅期待子进程结束,还借助 WEXITSTATUS 宏取到了子进程的 exit code。

以上就是本文的全部内容,希望对大家的学习有所帮助,也期望大家多多支持网页设计。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-120295-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 冯兴一
        冯兴一

        如果他要耍赖

      • 栾涛
        栾涛

        赶紧买两袋南方黑芝麻糊压压惊

      每日福利
      热点图片
      拼命载入中...