Linux--进程状态

ok,今天我们来学习Linux中的进程状态

补充知识

1并行和并发

CPU执行进程代码,不是把进程代码执行完毕,才开始执行下一个。而是给每一个进程预分配一个 时间片,基于时间片,进行调度轮转(单CPU下),并发

  • a 并发:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发
  • b 并行:多个进程在多个CPU下分别同时进行,这称之为并行

2时间片

Linux/windows民用级别操作系统一般都是分时操作系统(调度任务追求公平)与之对应的还有实时操作系统

3进程具有独立性(原子性)

进程状态查看

ps aux / ps axj 命令
  • a:显⽰⼀个终端所有的进程,包括其他⽤⼾的进程。
  • x:显⽰没有控制终端的进程,例如后台运⾏的守护进程。
  • j:显⽰进程归属的进程组ID、会话ID、⽗进程ID,以及与作业控制相关的信息
  • u:以⽤⼾为中⼼的格式显⽰进程信息,提供进程的详细信息,如⽤⼾、CPU和内存使⽤情况等

Linux内核源代码

        为了弄明⽩正在运⾏的进程是什么意思,我们需要知道进程的不同状态。⼀个进程可以有⼏个状 态(在Linux内核⾥,进程有时候也叫做任务)。

下⾯的状态在kernel源代码⾥定义:

 /*
 *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磁盘休眠状态(Disksleep)有时候也叫不可中断睡眠状态(uninterruptiblesleep),在这个 状态的进程通常会等待IO的结束。

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

  • 前台进程(标识有+)可以用Ctrl+C结束进程
  • 后台进程(标识没有+)只能用命令行 kill杀死该后台进程

X死亡状态(dead):这个状态只是⼀个返回状态,你不会在任务列表⾥看到这个状态。

Z僵尸状态(zombie): 下面详细介绍

    等待的本质

    • 1.阻塞
    • 2.挂起

    阻塞状态/休眠状态

    例如以下代码

    #include<stdio.n>
    
    
    int main()
    {
        int cnt = 0;
        while(1)
        {
            printf("hello ,linux cnt = %d\n",cnt++);
            
        }
        return 0;
    }

    !!!使用进程查看命令,查看进程状态,绝大部分是S状态(睡眠状态/阻塞状态)有一小部分在R状态(理论上刷新查看一定次数可以看到),这是因为CPU在等待 I/O流,CPU的o速度很快,而显示器跟不上CPU的处理速度,所以CPU基本上处于睡眠状态,在等待I/O流的输出,只有CPU在显示屏输出完CPU处理的数据后,该进程才会再次进入R状态(运行状态)。

    如果将printf语句注释掉,再次查看进程状态就会发现,一直处于R运行状态,这是因为没有I/O流的占用,一直都在判断,都在运行该程序,所以一直都是R运行程序

    echo &? 查看最近程序退出时的退出信息

    Z(zombie)-僵尸进程 

    • 僵死状态(Zombies)是⼀个⽐较特殊的状态。当进程退出并且⽗进程(使⽤wait()系统调⽤,后 ⾯讲)没有读取到⼦进程退出的返回代码时就会产⽣僵死(⼫)进程
    • 僵死进程会以终⽌状态保持在进程表中,并且会⼀直在等待⽗进程读取退出状态代码。
    • 所以,只要⼦进程退出,⽗进程还在运⾏,但⽗进程没有读取⼦进程状态,⼦进程进⼊Z状态 来⼀个创建维持30秒的僵死进程例⼦

    总结:Z维持退出信息,方便父进程和操作系统进行查询

    来⼀个创建维持30秒的僵尸进程例⼦:

     #include <stdio.h>
     #include <stdlib.h>
     int main()
     {
         pid_t id = fork();
         if(id < 0){
             perror("fork");
             return 1;
         }
         else if(id > 0){ //parent
             printf("parent[%d] is sleeping...\n", getpid());
             sleep(30);
         }else{
             printf("child[%d] is begin Z...\n", getpid());
             sleep(5);
             exit(EXIT_SUCCESS);
         }
         return 0;
    }

    编译并在另⼀个终端下启动监控

    开始测试


    看到结果

    僵⼫进程危害

    • 进程的退出状态必须被维持下去,因为他要告诉关⼼它的进程(⽗进程),你交给我的任务,我 办的怎么样了。可⽗进程如果⼀直不读取,那⼦进程就⼀直处于Z状态?是的!
    • 维护退出状态本⾝就是要⽤数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中, 换句话说,Z状态⼀直不退出,PCB⼀直都要维护?是的!
    • 那⼀个⽗进程创建了很多⼦进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数 据结构对象本⾝就要占⽤内存,想想C中定义⼀个结构体变量(对象),是要在内存的某个位置 进⾏开辟空间!
    • 内存泄漏?是的!
    • 如何避免?

    孤儿进程

    • ⽗进程如果提前退出,那么⼦进程后退出,进⼊Z之后,那该如何处理呢?
    • ⽗进程先退出,⼦进程就称之为“孤⼉进程”
    • 孤⼉进程被1号init进程领养,当然要有init进程回收喽
     #include <stdio.h>
     #include <unistd.h>
     #include <stdlib.h>
     int main()
     {
         pid_t id = fork();
         if(id < 0){
             perror("fork");
             return 1;
         }
         else if(id == 0){//child
             printf("I am child, pid : %d\n", getpid());
             sleep(10);
         }else{//parent
             printf("I am parent, pid: %d\n", getpid());
             sleep(3);
             exit(0);
         }
         return 0;
     }

    少年没有乌托邦,心向远方自明朗!

    如果这个博客对你有帮助,给博主一个免费的点赞就是最大的帮助
    欢迎各位点赞,收藏关注
    如果有疑问或有不同见解,欢迎在评论区留言
    后续会继续更新大连理工大学相关课程和有关Linux的内容和示例
    点赞加关注,学习不迷路,好,本次的学习就到这里啦!!!

    ok,我们下次再见!

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

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

    打赏作者

    头发尚存的猿小二

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

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

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

    打赏作者

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

    抵扣说明:

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

    余额充值