当前位置:   article > 正文

Linux中进程的六种状态_linux进程状态有哪些

linux进程状态有哪些

目录

R运行状态(running)

S睡眠状态(sleeping)

D磁盘休眠态(Disk sleep)

Z僵尸状态(zombie)

僵尸进程

僵尸进程的危害

T停止状态(stopped)

X死亡状态(dead)

特殊的进程:孤儿进程


 

R运行状态(running)

并不意味着进程一定处在运行中,它表示进程处在运行中或者运行队列里

这和我们平时的理解有所不同,如果想知道其中缘由,需要我们深入理解cpu是如何运行进程的:


准备好运行的进程会链接在一起,形成一个运行队列。

OS会创建一个管理运行队列的结构体,结构体中含有指向进程头部和尾部的指针。

当cpu运行进程时,可以通过结构体的指向,直接获取队列头部的进程。

调度器:相当于一个函数,将运行队列作为参数传进来,就可以找到所有正在排列的所有进程。

**运行态:处于运行队列的进程就叫做处于运行状态。

在运行队列里的含义就是:我已经准备好了,可以随时被调用。

一个进程只要把自己放到CPU上开始运行了,是不是要一直到执行完毕,才把自己放下来?

不是!!!

如果我写一个while(1)死循环,那么在这个循环跑的时候,其他所有进程都不能运行,实际生活的经验告诉我们,这显然是不可能的。

为了防止一个进程在cpu上下不来,每一个进程都有一个叫做时间片的概念。比如 int t =10ms。当跑完时间片上的时间以后,进程就会从cpu上下来,放到队列的尾部。1s内可以跑很多个进程,所以用户看到每个进程都在跑。

在一段时间内,所有进程的代码都会被执行,叫做并发执行。

代码中存在大量的把进程从cpu上放上去和拿下来的动作,这个动作叫做进程切换。

S睡眠状态(sleeping)

表示进程等待某件事件完成,又叫做阻塞状态。这里的睡眠指可中断睡眠。

在学习c语言的过程中,我们都用过scanf函数,当提示我们从键盘输入数据但我们还未输入时,整个程序是不会往下继续进行的,此时这个进程就处于阻塞状态。

 --------------------------------------------------------------------------------------------------------------------------------

在操作系统中绝大多数进程都处于阻塞状态,操作系统内存不足时,会想办法节省出来一些内存资源。

因为在阻塞状态时,进程的数据和二进制代码是用不到的,所以操作系统就将一部分进程的二进制代码放入磁盘中存储,仅仅留下PCB排队。这个过程叫做唤出

当需要用到数据和二进制代码时,再将其加载进内存。这个过程叫做唤入

D磁盘休眠态(Disk sleep)

也叫作不可中断睡眠态(深度睡眠),在这个状态的进程通常会等待IO状态的结束

 都已经有了睡眠状态,为什么还有增加一个不可中断睡眠态?

上述三者只是各司其职,但却造成了数据的缺失,这时设计上的缺陷,所以引入了D状态。

D状态相当于有了一个免死金牌,即使是操作系统也不能杀掉这种状态下的进程。

Z僵尸状态(zombie)

僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵死进程。

僵尸进程会以终止状态保持在进程表中,并且一直等待父进程读取状态退出代码。

所以,只要子进程退出,父进程还在运行,但是父进程没有读取子进程状态,子进程进入Z状态

类似当一个人去世以后,必须要等到他的亲属得到通知以后,才能进行下一步的处理。

在进程中,子进程挂掉以后,要将执行结果等一些信息告诉父进程,父进程知道以后,才能被清理。

僵尸进程

代码:

  1. #include<stdio.h>
  2. #include<sys/types.h>
  3. #include<unistd.h>
  4. int main()
  5. {
  6. printf("我是一个进程啦,my id is:%d,my parent id:%d\n",getpid(),getppid());
  7. sleep(2);
  8. pid_t id =fork();
  9. if(id == 0){
  10. int cur=5;
  11. while(cur){
  12. cur--;
  13. printf("我是子进程,pid:%d,ppid:%d\n",getpid(),getppid());
  14. sleep(1);
  15. }
  16. }
  17. else if(id>0){
  18. while(1){
  19. printf("我是父进程,pid:%d,ppid:%d\n",getpid(),getppid());
  20. sleep(1);
  21. }
  22. }else{
  23. }
  24. return 0;
  25. }

运行结果:

僵尸进程的危害

如果父进程一直不读取子进程的退出状态,那么子进程就一直处于Z状态?是的!

维护退出状态本质就是用数据维护,也属于进程的基本信息,存储在task_struct(PCB)中,换句话说,如果Z状态一直不退出,那么PCB一直都要维护?是的!

如果一个父进程有很多个子进程,就是不回收,是不是会造成内存的浪费?是的!

也就是说造成了内存泄漏?是的!

在后续的学习这中会更新避免出现僵尸进程的方法。

T停止状态(stopped)

可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行

X死亡状态(dead)

这个状态只是一个返回状态,你不会在任务列表里看到这个状态。

目前为止,出现的值得关注的进程状态已经全部讲完,下面我们来认识另外一种特殊的进程


孤儿进程

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

代码:

  1. #include<stdio.h>
  2. #include<sys/types.h>
  3. #include<unistd.h>
  4. int main()
  5. {
  6. printf("我是一个进程啦,my id is:%d,my parent id:%d\n",getpid(),getppid());
  7. sleep(2);
  8. pid_t id =fork();
  9. if(id ==0 ){
  10. while(1){
  11. printf("我是子进程,pid:%d,ppid:%d\n",getpid(),getppid());
  12. sleep(1);
  13. }
  14. }
  15. else if(id>0){
  16. int cur=5;
  17. while(cur){
  18. cur--;
  19. printf("我是父进程,pid:%d,ppid:%d\n",getpid(),getppid());
  20. sleep(1);
  21. }
  22. }
  23. else{
  24. }
  25. return 0;
  26. }

执行结果:

 注:S+中的+表示在前台运行的意思,在前台运行的可以通过ctrl+c停止,在后台运行的不行,要通过信号,kill -9 PID

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

闽ICP备14008679号