• 进程状态和优先级【Linux】


    1.进程状态的分类

    在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 */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在下面的状态讲解中是概念定义加实操的方式,感兴趣的老铁可以边看边做。

    1.1.R运行状态

    R运行状态:处在运行状态的进程不一定正在运行,运行状态的定义是进程在运行队列中的进程就是运行状态。

    //测试代码
    #include 
    #include 
    
    int main()
    {
    	while()
    	{}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    1.2. S睡眠状态

    S睡眠状态:意味着进程在等待事件的完成(这里的睡眠有时候也叫做可中断睡眠)

    //测试代码
    #include 
    #include 
    
    int main()
    {
    	while()
    	{
    		printf("hello bit\n");
    	}
    	return 0;
    }
    //注:问:为什么这里加个printf进程状态就变成S状态了?
    //答:printf是一个需要访问硬件(显示器)的库函数,由于硬件相比于CPU速度相对较慢,而CPU不可能安安静静的等待进程访问硬件,所以OS把这个进程状态设置为S,让进程自己慢慢的等待硬件,CPU继续执行运行队列下一个进程。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    1.3.D磁盘休眠状态

    D磁盘休眠状态:有时候也叫做不可中断睡眠状态,在这个状态的进程通常会等待IO结束。

    这个状态的场景比较难以实现,只有系统在高IO的时候,系统才能出现这个状态。当一个机器中这个状态大面积出现的时候,离机器挂掉也不远了。这里我们也不在实现了。

    1.4.T停止状态

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

    1.4.1.kill -l指令

    指令:kill -l
    作用:查看系统中的信号
    在这里插入图片描述

    //此处的测试用例和睡眠状态的测试用例一样,我们需要在睡眠状态的时候给它发送一个暂停信号
    #include 
    #include 
    
    int main()
    {
    	while()
    	{
    		sleep(1);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    给S+状态的进程发送一个19号信号
    在这里插入图片描述
    如果在给T状态的进程发送18号信号,它会变成一个后台进程(s+代表前台进程,s代表后台进程)
    在这里插入图片描述

    1.4.2.前台进程和后台进程

    前台进程:是在终端中运行的命令,那么该终端就为进程的控制终端,一旦这个终端关闭,这个进程也随之消失。
    后台进程:也叫守护进程(Daemon),是运行在后台的一种特殊进程,不受终端控制,它不需要终端的交互;Linux的大多数服务器就是使用守护进程实现的。比如Web服务器的httpd等。

    1.5.X死亡状态

    X死亡状态:这个状态是一个返回状态,你不会在任务列表里看到这个状态

    2.进程状态查看

    指令:ps aux / ps axj命令
    作用:查看系统中的所有进程
    在这里插入图片描述

    3.Z(zombie)僵尸进程

    • 僵尸进程是一个比较特殊的状态,当子进程退出,但是父进程没有回收子进程,就会产生僵尸状态
    • 僵尸进程会以终止状态保持在进程表中,并且会一直等待父进程读取退出码。
    • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程会进入Z状态。

    测试代码:

    #include 
    #include 
    #include 
    int main()
    {
        pid_t id = fork();
        if(id == 0)
        {                                                                                                                  
            //child
            int cnt = 5;
            while(cnt--)
            {
                printf("I am child process:pid = %d,ppid = %d\n",getpid(),getppid());
                sleep(1);
            }
            //子进程循环五次变会退出
            exit(-1);
        }
        else if(id > 0)
        {
        	//让父进程一直循环,但并没有回收子进程的资源
            while(1)
            {
                printf("I am parent process:pid = %d,ppid = %d\n",getpid(),getppid());
                sleep(1);
            }
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    在这里插入图片描述

    3.1.僵尸进程的危害

    • 进程退出状态必须被维持下去,因为它要告诉它的进程(父进程)你交给我的任务,我办得怎么样。可是,如何父进程一直不读取,那子进程一直处于Z状态?对的。
    • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在tast_struct(PCB)中,换句话说,Z状态一直不退出,PCB一直要维护吗?是的。
    • 那一个父进程创建了许多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构对象本身就要占用内存。
    • 会造成内存泄漏?是的。

    4.孤儿进程

    孤儿进程:如果父进程先退出,子进程被1号Init进程领养,这时子进程就称为孤儿进程

    //测试代码,让父进程循环10,退出程序,子进程一直跑
    #include 
    #include 
    #include 
    
    int main()
    {
        pid_t id = fork();
        if(id == 0)
        {
            //child 
            while(1)
            {
                printf("I am child process:pid = %d,ppid = %d",getpid(),getppid());  
                sleep(1);                   
            }  
        }                                   
                                            
        if(id > 0)                                                                                                         
        {                                   
            //parent                        
            int cnt = 10;                   
            while(cnt--)                    
            {                                                                         
                printf("I am parent process:pid = %d,ppid = %d",getpid(),getppid());  
                sleep(1);                   
            }                               
            exit(-1);                                                                                        
        }                                                                                                    
                                                                                                             
        return 0;    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    注意:孤儿进程并不会造成内存泄漏,因为子进程被1号进程领养了,1号进程会读取子进程的返回信息。

    5.进程优先级

    5.1.基本概念

    • CPU资源分配先后顺序,就是指进程的优先权
    • 优先权高的进程有优先执行权力,配置进程的优先级对多任务环境很有用,可以改善系统性能。
    • 还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU上,可以大大改善系统整体性能。

    5.2.查看系统进程

    指令:ps -l
    作用:查看系统性能
    在这里插入图片描述

    • UID:代表执行者的身份。
    • PID:代表这个进程的代号。
    • PPID:代表这个进程是由那个进程发展而衍生而来,亦即父进程的代号。
    • PRI:代表这个进程可执行的优先级,其值越小越早执行。
    • 代表这个进程的nice值。

    5.3.PRI and NI

    进程优先级 = 老的优先级 + nice值(其中老的优先级恒等于80,nice值的范围是-20到19,通过改变nice的大小,更改进程的优先级)。

    • PRI越小,进程优先级越高
    • NI(nice)表示进程可执行优先级的修正数据
    • 通过调整nice的值,来改变优先级,但本身nice值不是进程的优先级,只是nice值会影响到优先级

    5.4.用top命令更改已存在进程的nice值

    步骤:进入top后按“r”->输入进程的PID->输入nice值 ->q退出
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    Windows自动化重启python脚本
    C和指针 第14章 预处理器 14.2 #define
    小程序商城框架源码 小程序源码带前端+后台+数据库
    IP组播简介
    大话STL第十期终章——算法
    Android handlerThread并发了解
    好的内容回复区
    代码随想录算法训练营Day41 (day40 休息) | 动态规划(3/17) LeetCode 343. 整数拆分 96.不同的二叉搜索树
    Python基础内容训练5(常用的数据类型-----字典)
    内网-2(代理)
  • 原文地址:https://blog.csdn.net/SASCII/article/details/127891482