当前位置:   article > 正文

Linux-进程状态&僵尸进程&孤儿进程_-t命令是表示当前查询进成状态为僵尸状态吗

-t命令是表示当前查询进成状态为僵尸状态吗

####一、Linux进程状态

#####在我们的操作系统中,可以同时运行多个程序,而程序在内存中则是一个个的进程,在windows下我们打开任务管理器就可查看对应进程的状态。Linux下可以通过ps命令查看,Linux上进程主要有以下几种状态:
#####<1>运行状态 R(TASK_RUNNING)
#####当进程正在被CPU执行,或已经准备就绪随时可被调度执行,则称该进程为处于运行状态(running)。所谓就绪状态就是该进程已经具有执行所需的条件,随时可被调度执行,但是还在就绪队列中尚未被调度。
#####<2>可中断睡眠状态 S(TASK_INTERRUPTIBLE)
#####由于cpu同时可执行的进程有限,所以我们查看进程状态时会有大多数的进程都处于此状态。当进程处于可中断睡眠状态时,系统不会调度该进程执行。只有当系统产生一个中断或者释放了该进程正在等待的资源,或者该进程收到一个信号,就可以唤醒该进程并将状态转换到运行状态(R)。
#####<3>不可中断睡眠状态 D(TASK_UNINTERRUPTIBLE)
#####与可中断睡眠状态类似,但处于该状态的进程不响应异步信号,此状态存在的意义就在于,内核的某些处理流程是不能被打断的。如果响应异步信号,程序的执行流程中就会被插入一段用于处理异步信号的流程(这个插入的流程可能只存在于内核态,也可能延伸到用户态),于是原有的流程就被中断了。
#####<4>暂停状态 T(TASK_STOPPED)
#####当进程收到信号SIGSTOP、SIGTSTP、SIGTTIN或SIGTTOU时就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。
#####<5>僵死状态 Z(TASK_ZOMBIE)
#####当子进程已停止运行,但其父进程还在运行并且没有询问其状态时,则称该子进程处于僵死状态。僵死进程会以终止状态保持在进程表中,直到等待父进程读取退出状态码。
#####<6>退出状态 X ( TASK_DEAD - EXIT_DEAD)
#####进程将被置于EXIT_DEAD退出状态,这意味着接下来的代码立即就会将该进程彻底释放。该状态是非常短暂的,几乎不可能通过ps命令捕捉到。


#####补充:STAT状态位常见的状态字符

#####D 无法中断的休眠状态(通常 IO 的进程);
#####R 正在运行可中在队列中可过行的;
#####S 处于休眠状态;
#####T 停止或被追踪;
#####W 进入内存交换 (从内核2.6开始无效);
#####X 死掉的进程 (基本很少見);
#####Z 僵尸进程;
#####< 优先级高的进程
#####N 优先级较低的进程
#####L 有些页被锁进内存;
#####s 进程的领导者(在它之下有子进程);
#####l 多进程的(使用 CLONE_THREAD, 类似 NPTL pthreads);
#####+ 位于后台的进程组;
#####使用ps a可查看当前所有进程:
这里写图片描述


####二、僵尸进程
#####**<1>先来构造一个僵尸进程的例子:**我们在前面已经了解到一个子进程在其父进程没有调用wait()或waitpid()的情况下退出,如果其父进程还存在而一直不调用wait(),则该僵尸进程将无法回收,等到其父进程退出后该进程将被init回收。在这个过程中子进程已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,这个时候该子进程称为一个僵尸进程。这个子进程就是僵尸进程。例:


  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <stdlib.h>
  4 
  5 
  6 int main()
  7 {
  8     pid_t id = fork();
  9     if(id < 0){
 10         perror("fork");
 11         return 1;
 12     }else if(id > 0){
 13         printf("parent[%d] is sleeping\n",getpid());
 14         sleep(30);
 15     }else{
 16         printf("child[%d] is begin\n",getpid());
 17         sleep(5);
 18         exit(1);
 19     }
 20 
 21     return 0;
 22 }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

#####我们在shell下同时开启两个终端,一个下运行以上程序,另外一个在执行过程中使用grep抓取stat状态为zZ进程,通过结果的显示我们可以看出来在该进程执行时父进程状态为Z,成为了僵尸进程

ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'

  • 1
  • 2

#####<2>结果分别如下:
#####我们通过fork()创建一个子进程,父进程执行30s,子进程执行5s后就退出,并且父进程没有使用wait或waitpid的方式来获取子进程的退出信息,此时子进程就会出现僵尸进程的现象。
这里写图片描述
这里写图片描述


#####<3>避免僵尸进程的方法:
#####⒈父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起,相关用法可以通过man命令查看。
#####⒉ 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler,因为子进程结束后, 父进程会收到该信号,可以在handler中调用wait回收。
#####⒊ 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCHLD,SIG_IGN) 通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收, 并不再给父进程发送信号。
#####⒋ 还有一些技巧,就是fork两次,父进程fork一个子进程,然后继续工作,子进程fork一 个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收 还要自己做。


#####<4>僵尸进程的危害:
#####假设这样一个情景,我们有一个父进程在不断的创建子进程,每个子进程的存活时间都很短,父进程对子进程的终止状态都不管不顾,任由发展下去,子子孙孙,系统中就会存在许多的僵尸进程,更重要的是每一个僵尸进程都还没占着对应的进程列表,进程列表可是临界资源是有限的,时间一长内存中就没有多余的地方再让我们创建进程了。


####三、孤儿进程
#####<1>同样通过构造一个例子来理解什么叫孤儿进程,此场景就和名字一样通俗易懂,所谓的“孤儿”,就是失去了“父亲”,也就是说在子进程还在执行时,父进程就已经退出了。看例子:

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

 int main()
 {
      pid_t id  = fork();
      
      if(id < 0){
          perror("for");
          return 1;
      }else if(id == 0){
          printf("start:im child[%d],parent is [%d]\n",getpid(),getppid());
          sleep(10);
          printf("finish:im child[%d],parent is [%d]\n",getpid(),getppid());
      }else{
          printf("im father[%d]\n",getpid());
          sleep(2);
      }   
      
      return 0;
  }

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

#####<2>运行结果及分析:
#####我们可以看出本来子进程的父进程Pid为2420,但是我们让父进程sleep两秒后就结束了,此时子进程依然还在运行,等子进程sleep完成后,此时父进程已经不在了,新的父亲的pid为1,也就是系统中的init进程,也可以说该子进程被init进程所接管。
这里写图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/308560
推荐阅读
相关标签
  

闽ICP备14008679号