1. linux内核进程调度算法源码分析 目的:通过阅读linux源代码,分析研究linux的进程调度策略和算法。 内容:以源码为依据,分析如下问题 1) 进程调度队列是如何组织的; 2) 三种调度类型(SCHED_FIFO, SCHED_RR, SCHED_OHTER)的实现过程; 3) 优先级是如何定义和动态变化的; 4) 时间片的赋值?它与优先级的关系? 重点分析内核数据结构task_struct(在include/linux/sched.h中)和调度函数schedule()(在kernel/sched.c中
时间: 2024-03-28 15:38:02 浏览: 98
进程调度队列是如何组织的:
在 Linux 内核中,进程调度队列是由多个就绪队列(runqueue)组成的。每个 CPU 都有一个就绪队列,用于保存可以被调度的进程。就绪队列是一个双向链表,每个链表节点对应一个进程。就绪队列使用了一些优化技巧,例如旋转数组(rotating bitmap)和红黑树(red-black tree),以提高调度效率。
三种调度类型(SCHED_FIFO, SCHED_RR, SCHED_OTHER)的实现过程:
Linux 内核中支持三种调度类型:
- SCHED_FIFO:先进先出调度策略,进程一旦被调度,将一直占用 CPU 直到自愿放弃或者被其他进程抢占。
- SCHED_RR:时间片轮转调度策略,进程被分配固定的时间片,当时间片用完或者进程主动放弃 CPU 时,进程就会被放回到就绪队列中,等待下一次调度。
- SCHED_OTHER:CFS(Completely Fair Scheduler)调度策略,基于进程的虚拟运行时间(vruntime)来决定进程的优先级。优先级较高的进程被调度的机会更高。
在 Linux 内核中,这三种调度类型的实现都是基于调度类(sched_class)的概念。每个调度类都包含了一组函数指针,用于实现进程调度相关的操作。不同的调度类实现不同的调度策略。
优先级是如何定义和动态变化的:
在 Linux 内核中,进程的优先级是一个动态变化的值,取值范围为 -20 到 19。优先级较高的进程会更容易被调度。进程的优先级由调度类的实现决定,不同的调度类可以有不同的优先级计算方式。
时间片的赋值?它与优先级的关系?
在 Linux 内核中,时间片的赋值与优先级有关。时间片的大小由进程的优先级决定,优先级越高的进程分配的时间片越长。具体来说,时间片的大小可以通过以下公式计算:
time_slice = 100 * 2 ^ (MAX_PRIO - prio)
其中,MAX_PRIO 是进程优先级的最大值,prio 是进程的优先级。时间片的单位是 jiffies(时钟滴答数),具体的大小可以通过 kernel/sched/core.c 中的 time_slice() 函数计算。
重点分析内核数据结构 task_struct(在 include/linux/sched.h 中)和调度函数 schedule()(在 kernel/sched.c 中):
task_struct 结构体是 Linux 内核中描述进程的主要数据结构,其中包含了进程的各种信息,包括进程 ID、优先级、状态等等。task_struct 结构体比较庞大,其中包含了多个子结构体,例如 thread_info、mm_struct、fs_struct 等等。
schedule() 函数是 Linux 内核中实现进程调度的核心函数,它由内核定时器触发,用于从就绪队列中选择下一个需要运行的进程。schedule() 函数首先会检查当前 CPU 上是否有正在运行的进程,如果有,则不进行调度;否则,它会从就绪队列中选择下一个进程,并将其调度到 CPU 上运行。如果就绪队列为空,则 schedule() 函数会将当前 CPU 切换到 idle 进程上,以节省 CPU 资源。
阅读全文