Linux--进程状态


为了弄明白正在运行的进程是什么意思,我们需要知道进程的不同状态,一个进程有如下几个状态

进程的状态

进程状态的意义:方便操作系统快速判断进程,完成特定的功能,比如调度,它的本质是将进程进行分类

/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
  • R运行状态(running):并不意味着进程一定在运行中,它表明进程要么是在运行中,要么是在运行队列中
  • S睡眠状态(sleeping):意味着进程在等待事件完成(这里的睡眠有时也叫做可中断睡眠
  • D磁盘休眠状态(Disk sleep):有时候也叫不可中断睡眠状态,在这个状态的进程通常会等待IO的结束
  • T停止状态(stopped):可以通过发送SIGSTOP信号给进程来停止进程。这个被暂停的进程可以通过发送SIGCONT信号让进程继续运行
  • X死亡状态(dead):这个状态只是一个返回状态,不会在任务列表里看到这个状态
R状态

前面我们讲到R状态的进程并不一定代表那个进程就在运行中,我们知道,CPU要管理进程是通过进程控制块PCB,而在任意时刻一定有许多的进程等待CPU的调用,就会有一个运行时队列(run_queue)来维护要调用的进程,这个运行时队列里面就是一个个的进程控制块,所以只要在运行时队列中 就是R状态。如下图

在这里插入图片描述

例子

    1 #include<iostream>
    2 #include<unistd.h>
    3 using namespace std;
    4 int main()
    5 {
    6   while(true)
    7   {                        
   11     cout << "hello ybb" << endl;
   12   }
   13   return 0;
   14 }
  ~

在这里插入图片描述

S状态和D状态

当我们完成某种任务的时候,有可能当前的条件不具备,需要进程进行某种等待。比如我们在使用scanf函数的时候,需要我们输入之后程序才会继续往下执行。这就是因为程序在等待我们从键盘上输入,此时程序就是S状态。我们知道运行时状态有一个运行时队列(run_queue)来维护进程,同样的等待状态也有一个等待队列(wait_queue)来维护我们在等待的进程,等到所有条件都具备时,就进入运行时状态。我们把,从运行状态的task_struct(run_queue),放到等待队列中,就叫做挂起等待(阻塞),从等待队列,放到运行时队列,被CPU调度就叫做唤醒进程

在这里插入图片描述

  1 #include<iostream>  
  2 #include<unistd.h>  
  3 using namespace std;  
  4 int main()  
  5 {  
  6   while(true)  
  7   {  
  8    // sleep(10);  
  9    int i = 0;  
      cout << "请输入一个数字:";
 10    cin >> i;  
 11    cout << "hello ybb" << endl;  
 12   }                        
 13   return 0;                
 14 } 

在这里插入图片描述

  • S状态:又称为可中断睡眠,或者浅度睡眠
  • D状态:称为不可中断睡眠,或者深度睡眠,举个例子,假如我们在向磁盘中写数据,进程在等待磁盘写成功或写失败的返回值,此时进程就处于等待状态。而如果此时操作系统发现这个进程什么也没做就会过来杀进程,如果进程被杀磁盘写完后就找不到进程了,所以要把进程设置为D状态,进程就不会被操作系统杀
T状态

发送暂停信号将进程暂停,发送启动信号就将进程继续执行

测试

  1 #include<iostream>                      
  2 #include<unistd.h>
  3 using namespace std;
  4 int main()
  5 {
  6 
  7   while(true)
  8   { }
  9   return 0;
 10 }

在这里插入图片描述

PS:带加号的S+叫前台进程,此时可以用ctrl + c 杀死进程,不带加号的叫后台进程,./myproc &运行就是后台进程

X状态

释放进程资源 = 进程相关内核数据结构 + 代码和数据

Z状态–僵尸进程
  • 僵尸进程(Zombies)是一个比较特殊的状态。当子进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵尸进程。也就是说,子进程被杀死了,但是父进程没有回收子进程的资源,就产生了僵尸进程
  • 僵尸进程会以终止状态保持再进程表中,并且会一直等待父进程读取退出状态代码
  • 总结:只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

举个例子:

  1 #include<iostream>
  2 #include<unistd.h>
  3 using namespace std;
  4 int main()
  5 {
  6   pid_t pid = fork(); // 创建子进程
  7   if(pid == 0)
  8   {
  9     while(true)
 10     {
 11       cout << "hello ybb" << endl;
 12       sleep(2);
 13 
 14     }
 15   }                                                   
 16   else{
 17     sleep(50);
 18   }
 19 
 20 //  while(true)
 21 //  { }
 22   return 0;
 23 }

在这里插入图片描述

孤儿进程

  • 父进程如果提前退出,那么子进程退出后,进入Z状态之后,该如何处理?
  • 父进程先退出,子进程就称之为“孤儿进程”
  • 孤儿进程要被1号进程领养,所以孤儿进程由1号进程回收

举个例子

  2 #include<unistd.h>
  3 using namespace std;
  4 int main()
  5 {
  6   pid_t pid = fork();
  7   if(pid == 0)
  8   {
  9     cout << "我是子进程" << endl;
 10     sleep(50);
 11   }else{
 12     cout<< "我是父进程" <<endl;
 13     sleep(3);
 14     exit(0);
 15   }
 16   return 0; 
  }

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_yiyi_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值