【Linux】进程切换与优先级
优先级的实现优先级是进程的属性之一保存在PCB中。优先级中PCB中用整型表示其值越小表示优先级越高反之优先级越低。优先级是可以被修改的。但考虑到时间片的分时操作系统以及公平性优先级不能出现大幅度的修改。如上图我在Linux中使用执行查看当前正在运行的进程信息。可以看到红圈这两个值PRI表示进程的优先级其默认值是80NI表示进程优先级的修正数据称为nice值优先级的修改是通过nice值的修改实现的既最终的优先级 PRI NI如图通过renice指令来修改进程的优先级后我们再次查看进程信息可以发现第一个被修改的进程NI变成了10。最终的优先级变成了90。 说明默认值是不改变的优先级修改是通过nice值的修改而实现的补充UID如上图我们可以看到第三列有一个叫做UID的。那什么是UID呢UIDuser id表示用户标识符在linux中任何访问资源的操作都是进程实现的进程代表当前的用户。那系统是如何判断当前进程访问的权限的呢其实就是通过UID实现的通过进程中的UID与文件的UID相比较就可以判断出这个进程的访问权限是拥有者、所属组还是other。优先级的极值如图可知优先级的范围是[60 - 99]而nice值的范围是[-20 - 19]优先级范围设置的并不宽泛因为优先级范围设置过大会导致优先级低的进程长时间不能获得CPU资源进而导致进程饥饿。进程关系竞争性进程与进程之间是存在竞争关系的。CPU资源有限为获得CPU资源为了高效完成任务更合理的竞争相关资源便有了优先级。独立性多进程运行时各个进程之间是独享资源的互不干扰。并行多个进程在多个CPU下同时运行。并发多个进程在一个CPU下不停的切换运行在一段时间内让多个进程不断推进。进程切换进程的切换讨论范围在长代码与死循环代码因为较短的代码一瞬间就执行完毕了没有切换这一说法死循环进程死循环进程一段占用CPU执行代码会一直占用CPU吗并不会因为在计算机是分时操作系统在进程执行的过程中存在“时间片”。每个进程都有其适合的“时间片”本质其实就是计数器时间片达到时进程就会从CPU上剥离下来。所以死循环并不会一直占用CPU。CPU中的寄存器CPU中存在各种各样的寄存器用于保存当前正在运行进程的各种临时数据寄存器就是CPU内部的临时空间寄存器寄存器中的数据如何切换A进程占用CPU执行完一个时间片后要被剥离CPU进而执行下一个进程。那么当再次执行A进程时应该从上次执行位置开始继续向下执行。 这就意味着剥离时需要当前进程把自己的上下文记录下来以便于下一次继续执行。进程上下文保存到了哪里呢保存到了进程task_struct的TSS中TSS任务状态段下一次执行时之间覆盖CPU中的寄存器内容即可。对于以及执行过的进程才需要记录上下文对于之前还没有执行过的继承无需记录及其将寄存器内容初始化即可。Linux中真实的调度算法O(1)调度算法如上图runqueue是一个运行队列且一个CPU只有一个运行队列。queue[140]我们先来介绍一下queue[140]它的数据类型是struct task_struct*代码语言javascriptAI代码解释struct task_struct* queue[140]queue一共有140个元素一个元素就是一个进程队列其下标映射了优先级。前100个元素代表实时优先级我们不关心后40个代表我们上面所讲的普通优先级。我们之前讲到优先级的范围是60~99那对应在queue中的下标表示就是100~139x - 60 100)。比如优先级为64的进程就会链接至下标为104的节点下多个优先级一样的进程都会被依次链接在同一个进程队列中。bitmapbitmap[5]用于在queue中快速查找进程。bitmap的数据类型是unsigned int一个元素有32bit一个有5个这样的元素。用bit位记录进程信息0表示没有进程1表示有进程。从下标0开查询一次性查询32个位置并从最后一个“1”开始调用进程既优先级最高的进程位置。nr_active记录进程的个数当进程个数为0时不在使用bitmap查询进程。过期队列与活跃队列在图中我们可以看到有两个一模一样的队列结构蓝框与红框并由两个指针分别指向active活跃、expired过期。active指向的队列叫做活跃队列反之另一个叫过期队列。活跃队列上的进程是要占用CPU资源执行代码的。当活跃队列上的进程执行完一个时间片后会放到过期队列中的相应位置上优先级对应的位置。当活跃队列上的进程全部执行完时active指针与expired指针交换过期队列再次变为活跃队列继续执行之前的进程。Linux中进程切换的整体过程1.由bitmap在活跃队列中查询进程位置优先级最高进程的位置2.依次占用CPU资源执行相关进程3.时间片耗尽记录上下文后从CPU上剥离并链接至过期队列中4.直到活跃队列中没有进程指针交换再次循环至第一步补充如果新建了一个进程是插入活跃队列还是过期队列活跃队列新创建的进程应该尽快获得执行机会而不是放入已经执行过的过期队列中等待下一次的调度