关于Linux下的进程状态(进程篇)

Linux操作系统的一般进程状态

  • 新建:字面意思
  • 运行:task_struct结构体在运行队列中排队,就叫做运行态
  • 阻塞:等待非CPU资源就绪,阻塞状态
  • 挂起:当内存不足的时候,系统通过适当置换进程的代码和数据到磁盘,此时,进程的状态就叫做挂起。

关于阻塞

系统中一定是存在各种资源的,不仅仅是CPU资源,还有一些磁盘,网卡,显卡,键盘等等
这也就意味着系统中不仅仅只存在一种队列(运行队列、阻塞队列、、、)
示例:

        或者来说c语言中的scanf,c++中的cin,在系统中不也是在等待键盘资源的输入嘛,当我们的程序存在这些命令的时候,如果此时不在键盘上输入,那么此时的进程就处于阻塞状态。

关于挂起

         当系统中存在着大量的进程,那么一定会消耗大量的内存资源,此时,系统不得不通过把内存中的进程(对应的代码和数据)交换到磁盘,从而保证内存中仍有空余的空间,此时,对于被交换的进程来说,状态就被称为挂起。
(注意:此时内存中仍然保留进程对应的task_struct结构体。)

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): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态是一个返回状态,在任务列表里是无法查看到这个状态,瞬时性非常强,代表着进程已结束,告诉操作系统随时可以回收。
  • Z僵尸状态:一个进程已经退出,但是还不允许被操作系统释放,处于一个被检测的状态
示例:
注意,状态后面存在 + 这个符号,代表这是一个前台任务,可以随时被 Ctrl+c 终止掉
状态后面不存在 + 这个符号,代表这是一个后台任务(运行程序时,后面加上 & 符号),无法被 Ctrl+c 终止掉,可以通过 kill 发送信号终止
R状态
  1 #include<stdio.h>  
  2   
  3 int main()  
  4 {
  5     while(1)
  6     {}
  7                                                                                                                                                          
  8     return 0;
  9 }

S状态
 1 #include<stdio.h>  
  2   
  3 int main()  
  4 {
  5     while(1)
  6     {
  7         printf("I am process!\n");                                                                                                                       
  8     }
  9                                                                                                                                 
 10     return 0;                                                                                                                   
 11 }   

T状态:
t:通过gdb调试
 1 #include<stdio.h>  
  2   
  3 int main()  
  4 {
  5     while(1)
  6     {
  7         printf("I am process!\n");                                                                                                                       
  8     }
  9                                                                                                                                 
 10     return 0;                                                                                                                   
 11 }   

T:通过发送信号
睡眠状态和停止状态有什么区别呢?
  • S:等待某种资源,是阻塞状态
  • T:可以直接暂停,不会等待资源(比如gdb调试)

关于D状态:深度睡眠,不可被中断,不可以被被动唤醒

当服务器压力过大的时候,系统会通过一定的手段,杀掉一些进程,来起节省空间的作用!!
如图:当进程是S状态的时候,是有可能被系统干掉的,从而会导致传输失败。所以为了防止这样情况的发生,才有了D状态,他的意思是告诉系统,我是不可以被干掉的,只能等我传输成功,从睡眠中醒来才可以干掉我这个进程。

关于僵尸进程

  • 僵死状态(Zombies)是一个比较特殊的状态。
  • 没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
僵尸进程危害
          进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎么样了。可父进程如果一直不读取,那子进程就会一直处于Z状态!
        维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直都要维护!
如果一个父进程创建了很多子进程,就是不回收,是会造成内存资源的浪费!
        因为数据结构对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空间!所以一定会导致内存泄漏!
那么如何避免?后续会在进程等待中有所展开。 

关于孤儿进程

  • 父进程如果提前退出,子进程后退出,子进程进入Z之后,那该如何处理呢?
  • 父进程先退出,子进程就称之为“孤儿进程”
  • 孤儿进程被1号init进程领养,当然要有init进程回收喽。

示例:创建一个子进程,父进程运行5秒后结束,此时,子进程被1号进程收养。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值