
一、什么是进程优先级进程优先级就是CPU 资源分配的先后顺序。优先级高的进程拥有优先被 CPU 调度执行的权利。在多任务 Linux 环境下合理配置进程优先级可以优化整机性能我们还可以把低优先级后台任务绑定到指定 CPU 核心保障交互式程序响应速度。使用ps -l命令可以查看进程优先级相关字段ps -l字段含义UID进程执行者用户 IDPID进程 ID进程唯一标识PPID父进程 IDPRI进程优先级数值越小优先级越高NInice 值优先级修正数据二、PRI 和 NI (nice 值)1. 概念区分PRIPriority进程实际调度优先级数值越小进程越早被 CPU 执行该值由内核动态计算维护。NINice优先级修正值它本身不是优先级是用来修改 PRI 的修正量。计算公式PRI(new) PRI(old) nice注意PRI (old) 不是修改后的 PRI是内核默认基准优先级一般默认 80不是上一次修改后的 PRI 值。2.nice 取值范围nice 取值-20 ~ 19一共 40 个级别nice-20修正幅度最大进程优先级最高只有 root 用户可以设置负数 nicenice0进程默认 nice 值nice19修正幅度最小进程优先级最低普通用户只能把 nice 调大降低进程优先级不能设置负数root 用户可以设置全部范围。3. 重要提醒修改 nice 只是给调度器一个建议不代表进程会独占 CPULinux 调度器依然会保证所有进程都有机会运行不会出现进程永久饥饿。三、修改进程优先级的几种方式方式 1top 交互式修改运行中的进程输入top进入 top 监控界面按下r提示输入 PID输入目标进程 PID回车输入新的 nice 值回车完成修改q 退出 top使用ps -l验证修改结果。方式 2nice 命令启动程序的时候就指定优先级nice 用于还没启动的程序程序运行前设置 nice 值。# 以nice10启动程序降低优先级 nice -n 10 ./test # root设置高优先级 nice -n -10 ./test方式 3renice 命令修改已经运行的进程renice 针对已经在运行的进程通过 PID 修改 nice 值。# 将PID 1234的进程nice修改为5 renice 5 -p 1234 # root设置高优先级 renice -10 -p 1234方式 4系统调用代码中修改优先级头文件sys/time.h、sys/resource.h// 获取优先级 int getpriority(int which, int who); // 设置优先级 int setpriority(int which, int who, int prio);四、补充四个基础概念竞争、独立、并行、并发理解优先级需要先理解进程四个核心属性竞争性系统中进程数量很多但 CPU 核心数有限。进程之间会竞争 CPU、内存等硬件资源优先级就是用来规范竞争的规则让重要进程优先获取资源。独立性多个进程同时运行每个进程独享自己的资源虚拟地址空间、文件描述符等进程之间运行互不干扰一个进程崩溃一般不会直接影响其他进程。并行 Parallel多 CPU 核心多个进程真正同时运行。每个 CPU 核心跑一个进程同一时刻多个进程都在执行。并发 Concurrent单个 CPU 核心通过时间片快速切换进程。一段时间内多个进程交替向前推进微观上 CPU 同一时刻只跑一个进程宏观看起来多个程序 “同时运行”。通俗比喻并行多台咖啡机多队人同时做咖啡并发一台咖啡机多队人轮流使用机器。五、进程切换CPU上下⽂切换其实际含义是任务切换, 或者CPU寄存器切换。当多任务内核决定运⾏另外的任务 时, 它保存正在运⾏任务的当前状态, 也就是CPU寄存器中的全部内容。这些内容被保存在任务⾃⼰的堆栈中, ⼊栈⼯作完成后就把下⼀个将要运⾏的任务的当前状况从该任务的栈中重新装入CPU寄存器, 并开始下⼀个任务的运⾏, 这⼀过程就是context switch。参考Linux内核0.11代码注意时间⽚当代计算机都是分时操作系统没有进程都有它合适的时间⽚(其实就是⼀个计数器)。时间⽚到达进程就被操作系统从CPU中剥离下来。1.Linux2.6内核进程O(1)调度队列2.⼀个CPU拥有⼀个runqueue•如果有多个CPU就要考虑进程个数的负载均衡问题3-4-2 优先级•普通优先级100〜139我们都是普通的优先级想想nice值的取值范围可与之对应•实时优先级0〜99不关⼼3. 活动队列•时间⽚还没有结束的所有进程都按照优先级放在该队列•nr_active: 总共有多少个运⾏状态的进程•queue[140]: ⼀个元素就是⼀个进程队列相同优先级的进程按照FIFO规则进⾏排队调度,所以数组下标就是优先级•从该结构中选择⼀个最合适的进程过程是怎么的呢1. 从0下表开始遍历queue[140]2. 找到第⼀个⾮空队列该队列必定为优先级最⾼的队列3. 拿到选中队列的第⼀个进程开始运⾏调度完成4. 遍历queue[140]时间复杂度是常数但还是太低效了•bitmap[5]:⼀共140个优先级⼀共140个进程队列为了提⾼查找⾮空队列的效率就可以⽤5*32个⽐特位表⽰队列是否为空这样便可以⼤ 提⾼查找效率4. 过期队列•过期队列和活动队列结构⼀模⼀样•过期队列上放置的进程都是时间⽚耗尽的进程•当活动队列上的进程都被处理完毕之后对过期队列的进程进⾏时间⽚重新计算5.active指针和expired指针•active指针永远指向活动队列•expired指针永远指向过期队列•可是活动队列上的进程会越来越少过期队列上的进程会越来越多因为进程时间⽚到期时⼀直都存在的。•没关系在合适的时候只要能够交换active指针和expired指针的内容就相当于有具有了⼀批新的活动进程