• Linux操作系统~进程有哪些状态?


    目录

    R状态

     S/D状态

    什么是D状态

    T状态

    X状态

     Z状态

    什么是等待队列,什么是运行队列,什么是挂起/阻塞,什么叫唤醒进程

    对比宏观上操作系统的三种状态


      

            从操作系统宏观的概念上讲,进程有三种状态,就绪态,运行态和阻塞态,进程初始化完成后进入就绪态,然后操作系统就会从就绪的进程中调度进程给CPU执行,在CPU中运行的进程就处于运行态,当时间片完后又会变成就绪态在运行队列里面等待CPU下次调度;如果在运行中的进程需要某种外设或某些资源但是无法满足时(比如发起IO请求),处于运行态的进程就会进入阻塞态,等到运行条件满足以后,变为就绪态等待系统调用。


     在Linux系统中,进程的状态有六种:R,S,D,T,X,Z

    1.进程的状态信息在task_struct(PCB)里面

    2.进程状态的意义:方便OS快速判断进程的状态,完成特定的功能,比如调度,本质是一种分类

    R状态

    • R运行状态(running): 并不意味着进程一定在运行中(并不一定在使用CPU),它表明进程要么是在运行中要么在运行队列里

            让进程一直运行,通过ps指令查看当前进程的状态是R+,也就是运行状态(+表示处于前台的进程,如果我们想在后台运行进程./test6 &,这样在运行的时候加一个&即表示在后台)

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. while (1)
    6. {
    7. // cout << "running";
    8. }
    9. return 0;
    10. }
    1. [zebra@VM-8-12-centos cpp]$ ps -axj | head -1 && ps -axj | grep test6 | grep -v grep
    2. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    3. 3565 9911 9911 3565 pts/4 9911 R+ 1001 3:56 ./test6

     S/D状态

    • 当我们完成某种任务的时候,任务条件不具备,需要进程进行某种等待,S/D
    • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠(interruptible sleep),也就是可以随时被终止,接收中断信号,是一种浅度睡眠,比如调用sleep函数,可以随时被终止)。
    • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。(是一种深度睡眠,比如往磁盘中写数据,不可以随便终止进程,进程需要接受磁盘返回的信息

            进程等待用户输入的时候,会进入S状态

    1. #include
    2. using namespace std;
    3. int main()
    4. {
    5. int t;
    6. while (1)
    7. {
    8. cin >> t;
    9. }
    10. return 0;
    11. }
    1. [zebra@VM-8-12-centos cpp]$ ps -axj | head -1 && ps -axj | grep test6 | grep -v grep
    2. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    3. 3565 11425 11425 3565 pts/4 11425 S+ 1001 0:00 ./test6

    什么是D状态

            D状态是一种不可中断的睡眠状态。比如一个进程让磁盘你帮我写1G数据到磁盘里面去,磁盘开始忙了,进程就会进入D状态等待磁盘写入完成(因为这种等待状态是不允许被中断的,因为如果中断进程的等待,磁盘写入数据完成后,无法向原来的进程返回错误/正确信息,会导致一些问题)

    D状态就是深度睡眠,处于这种状态的进程不能被中断的(不可以被杀掉)

            进程在内核中某些不能被信号打断,例如对某些硬件设备进行操作时刻(等待磁盘Io,等待网络io等等)。

            进程处于D状态一般情况下很短暂不应该被top或者ps看到。

            如果进程在top和ps看到长期处于D状态,那么可能进程在等待IO时出现了问题导致进程一直等待不到IO资源,此时如果要处理掉这个D进程,那么只能重启整个系统才会恢复。因为此时整个进程无法被kill 掉


    T状态

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

            处于S状态的进程里面的数据可能会被更新,然后唤醒,处于T状态的进程是一种暂停状态,是彻底暂停了,也不会对其里面的一些数据进程更新。


    X状态

    • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态。表示进程彻底结束了,可以回收进程资源了(相关的数据结构+代码和数据),变成X状态后,这个进程几乎瞬间就会被清理掉,所以很难捕捉到处于这个状态下的进程。

     Z状态

    • Z僵尸状态(zombie):表示一个进程即将死亡的状态,此时可以保存进程退出的信息(比如进程为什么要退出),保存在task_struct里面

            所以当一个要进程退出的时候,会先进入Z僵尸状态,将进程的退出信息保存在task_struct里面,供父进程或者操作系统读取该信息,之后才会进入X死亡状态。

    1. 僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用读取)没有读取到子进程退出的返回代码时,子进程就是僵尸进程(处于僵尸状态)
    2. 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
    3. 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态
    4. 处于僵尸状态的进程叫做僵尸进程

            模拟子进程执行结束,父进程还没有结束的情况,此时子进程会变成僵尸进程,也就是处于Z状态。(后5s)

    1. #include
    2. #include
    3. #include
    4. using namespace std;
    5. int main()
    6. {
    7. pid_t id = fork();
    8. if (id == 0)
    9. {
    10. // 子进程
    11. cout << "这是子进程" << endl;
    12. sleep(5);
    13. }
    14. else if (id > 0)
    15. {
    16. // 父进程
    17. cout << "这是父进程" << endl;
    18. sleep(10)
    19. }
    20. else
    21. {
    22. //执行出错
    23. exit(-1);
    24. sleep(10);
    25. }
    26. }
    1. [zebra@VM-8-12-centos cpp]$ while :; do ps -axj | head -1 && ps -axj | grep test6 | grep -v grep; sleep 1; echo "============================================================="; done
    2. =============================================================
    3. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    4. =============================================================
    5. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    6. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    7. 5670 5671 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    8. =============================================================
    9. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    10. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    11. 5670 5671 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    12. =============================================================
    13. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    14. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    15. 5670 5671 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    16. =============================================================
    17. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    18. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    19. 5670 5671 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    20. =============================================================
    21. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    22. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    23. 5670 5671 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    24. =============================================================
    25. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    26. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    27. 5670 5671 5670 4932 pts/0 5670 Z+ 1001 0:00 [test6]
    28. =============================================================
    29. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    30. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    31. 5670 5671 5670 4932 pts/0 5670 Z+ 1001 0:00 [test6]
    32. =============================================================
    33. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    34. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    35. 5670 5671 5670 4932 pts/0 5670 Z+ 1001 0:00 [test6]
    36. =============================================================
    37. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    38. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    39. 5670 5671 5670 4932 pts/0 5670 Z+ 1001 0:00 [test6]
    40. =============================================================
    41. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    42. 4932 5670 5670 4932 pts/0 5670 S+ 1001 0:00 ./test6
    43. 5670 5671 5670 4932 pts/0 5670 Z+ 1001 0:00 [test6]
    44. =============================================================
    45. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    46. =============================================================
    47. PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
    48. =============================================================

     


    什么是等待队列,什么是运行队列,什么是挂起/阻塞,什么叫唤醒进程

            我们把从运行状态的task_struct(run_queue),放到等待队列中,就叫做挂起等待(阻塞)从等待队列,放到运行队列,被CPU调度就叫做唤醒进程

            当一个进程在运行的过程中,由于其某些运行条件还没就绪(比如要网络但是网卡了,或者需要等待IO,也就是需要使用外设了),就会被放到等待队列中,并且task_struct里面的状态位也会被改变为S/D。

    当进程处于S/D状态的时候,在一个等待队列里面等着使用外设(比如网卡,磁盘显示器等)

    等CPU的队列叫做运行队列,等外设的设备叫做等待队列

    所谓的进程,在运行的时候,有可能因为运行需要,可以会在不同的队列里

    在不同的队列里,所处的状态是不一样的

            当一个进程在R状态的时候,如果需要某种外设,但是外设在被使用,我就把你的状态变成S/D,然后把你的task_struct放到等待队列里面去

    对比宏观上操作系统的三种状态

            就绪态/运行态就是R状态,停止对应的就是X/Z状态,阻塞态对应的就是S/D/T状态(T状态很少使用)

  • 相关阅读:
    分享一下商城小程序怎么做
    数理统计笔记2:总体均值的抽样分布
    LVS----DR模式
    AQS之ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue阻塞队列特性及源码分析
    20220804NOI模拟赛--考后总结
    以数助实攻坚产业协作 蚂蚁集团数字科技业务亮相云栖大会
    【开源】基于JAVA的智能停车场管理系统
    Mybatis与Mybatis-Plus(注解与Xml)(单表与多表)
    MIPS寄存器堆
    Docker安装MySQL并使用Navicat连接
  • 原文地址:https://blog.csdn.net/qq_24016309/article/details/127632218