【Linux】进程优先级

1. 进程优先级

1.1优先级的概念

我们知道,同一时间,系统内的进程的有非常多个,这些进程中绝大多数都是需要访问到硬件的,比如键盘、鼠标、显示器、CPU等,但是同一时间,一个设备只能处理一个进程的需求,那么这些进程就必然需要确定访问硬件的先后顺序。对于CPU来说,确定一个进程先后运算的顺序的标准就是进程的优先级

优先级和权限的区分:

权限是指一件事情能不能做,优先级是指这件事情的顺序

为什么有优先级这个东西的存在:

因为系统内的资源是有限的,但是进程数量远大于资源数量,其中很多进程需要使用资源,所以要使用优先级来决定谁先使用资源

Linux下的优先级本质上就是PCB中的一个/几个数字

1.2查看系统进程

在Linux或Unix系统下,使用ps -l指令,将会输出类似以下的内容:

image-20231130103424929

  • UID:代表这个进程的执行者
  • PID:这个进程的唯一标识符
  • PPID:这个进程的父进程
  • PRI:这个进程的优先级,其值越小越先被执行
  • N I:代表这个进程的nice值

1.3PRI和NI的理解

Linux下确定进程优先级需要两个参数:PRI值(priority)和NI(nice)值。

在Linux下,我们认为:进程优先级 = 最初优先级(80) + NI

注意:

  • Linux下,最初优先级即是默认的PRI值:80
  • NI值是有取值范围的,NI的取值范围是[-20, 19]
  • 根据我们的结论可得PRI值有取值范围为:[60, 99]

根据上面的事实,我们可以得到以下结论:

  1. PRI值就是决定了一个进程的被执行顺序(值越小越先被执行)
  2. 由于PRI(new) = PRI(default) + NI、NI值是有范围的,所以PRI值可以通过修改NI值来修改
  3. NI不是进程的优先级,但是NI会影响到进程的优先级大小(可以理解成NI值是用来修正进程优先级的)

1.4 Linux下查看和修改进程优先级

在Linux下我们使用ps -l查看进程

image-20231130112704452

在两次查看之前,我们使用top指令查看当前的系统中各个进程的资源占用情况,此时

**修改进程优先级的方式:**输入top --> 输入r --> 输入进程id --> 输入修改后的NI值

  1. 使用root执行top指令或sudo提权执行top指令(这里是因为普通用户权限可能不够)

image-20231130141710948

  1. 输入r表示接下来要处理运行中的进程的内容,然后就会看到下图中的PID to renice,意思是要输入需要重设nice值的PID

image-20231130141756149

  1. 输入完PID之后回车,就会看到变成下图的样子,接下来要输入需要重设的nice值(这里我们设成了-20)

image-20231130141835714

  1. 通过ps -l指令来查看指定PID的进程,可以看到17291号进程的NI值被设置成了-20,PRI值也被改变成了60(初始是80)

image-20231130141923031

这样就完成了更改一个进程的优先级的操作。

最后,虽然我们可以通过修改 NI 值来调整进程优先级,但是我们一般都不会这样做,因为效果不大。

2. Linux下的一些其他的特性/概念

  • 竞争性:系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  • 独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰
  • 并行:多个进程在多个CPU下分别,同时进行运行,这称之为并行
  • 并发:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

竞争行的体现就是上述的第一个话题:进程优先级

2.1 进程独立性的体现

进程的独立性在父子进程之间的体现:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
    pid_t id = fork();
    while(1)
    {
        if(id > 0)
        {
            //parent
            printf("我是父进程,pid: %d, ppid:%d\n", getpid(), getppid());
            sleep(2);
        }
        else if(id == 0)
        {
            printf("我是子进程,pid: %d, ppid:%d\n", getpid(), getppid());
            int* p = NULL;
            *p = 10;//空指针解引用
            sleep(1);
        }
    }
    return 0;
}

image-20231130144724882

子进程崩溃之后,父进程依然能够正常运行

2.2 并发的方式:进程切换

一般我们使用的笔记本只有一个CPU,那么同一个时刻只有一个进程能够被CPU运算。但是事实上我们看到的电脑里面同时在运行着很多进程,并且他们都能够正常运行,让我们感觉似乎他们都在同时运行一样,这其实是进程切换的效果。

那么进程是如何切换的呢?

我们让每个需要在CPU进行运算的进程根据调度算法排序之后,每次让当前的进程只运行一段时间,然后再切换到另一个进程,继续运行,这样下去,那么就能达到我们觉得他们在同时运行的效果。

由于CPU的运行速度非常快,所以我们的时间单位似乎没有办法描述,所以在操作系统内部定义了一个单位叫做时间片,当一个时间片结束之后,就将进行进程的切换。

但是进程在运行的过程中肯定会产生很多的临时数据,这些数据在进程运行的时候会在寄存器内保存,但是当这个进程需要被切换出去的时候,这些数据是需要被保存的,因为下次该进程继续运行的时候还需要这些数据,那么这些临时数据的保存就被称为:上下文保护

在任何时刻,CPU里面的寄存器里面的数据,看起来是在大家都能看到的寄存器上,但是寄存器内的数据只属于当前运行的进程。虽然CPU内部只有一套寄存器硬件,但是寄存器保存的数据只属于当前进程,也就是说,寄存器硬件不是寄存器内的数据,这是两码事,寄存器被所有进程共享,但是寄存器里的数据时每个进程各自私有的。所谓的上下文保护指的就是保护寄存器内的数据

进程可以被切换下去,那么肯定也有被切换到运行的时候,那么这个进程如何被切换回来呢?

当进程恢复运行的时候,要进行上下文的恢复,该进程在次回到CPU继续运行时,重新加载恢复之前进行上下文保护的数据


本节完…

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

凌云志.

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

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

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

打赏作者

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

抵扣说明:

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

余额充值