练习1: 使用 Round Robin 调度算法(不需要编码)
完成练习0后,用make grade检查结果:
![[ab6实验/练习1.png)]](https://i-blog.csdnimg.cn/blog_migrate/6502cb338ab57247a6f52252d40814ce.png)
和练习1中说的一样,priority部分错误,其余正确。
- 请理解并分析sched_class中各个函数指针的用法,并接合Round Robin 调度算法描ucore的调度执行过程
- 请在实验报告中简要说明如何设计实现”多级反馈队列调度算法“,给出概要设计,鼓励给出详细设计
sched_class:
// The introduction of scheduling classes is borrrowed from Linux, and makes the
// core scheduler quite extensible. These classes (the scheduler modules) encapsulate
// the scheduling policies.
//调度类是从Linux中引入的,这使得核心调度程序具有相当的可扩展性。这些类(调度程序模块)封装了调度策略。
struct sched_class {
// 调度器名称
const char *name;
// 初始化运行队列
void (*init)(struct run_queue *rq);
// 将进程放入队列中,必须使用rq_lock调用
void (*enqueue)(struct run_queue *rq, struct proc_struct *proc);
// 将进程从队列中移除,必须使用rq_lock调用
void (*dequeue)(struct run_queue *rq, struct proc_struct *proc);
// 选择下一个可运行的任务
struct proc_struct *(*pick_next)(struct run_queue *rq);
// 更新调度器的时钟信息
void (*proc_tick)(struct run_queue *rq, struct proc_struct *proc);
/* for SMP support in the future
* load_balance
* void (*load_balance)(struct rq* rq);
* get some proc from this rq, used in load_balance,
* return value is the num of gotten proc
* int (*get_proc)(struct rq* rq, struct proc* procs_moved[]);
*/
};
这里我们可以看到五个函数:
sched_class_init,sched_class_enqueue,sched_class_dequeue,
sched_class_pick_next和sched_class_proc_tick
实现一个调度算法,必须具有这五个函数,才能实现一个调度算法。
RR调度算法
RR调度算法的调度思想是让所有
runnable态的进程分时轮流使用CPU时间。RR调度器维护当前runnable进程的有序运行队列。当前进程的时间片用完之后,调度器将当前进程放置到运行队列的尾部,再从其头部取出进程进行调度。RR调度算法的就绪队列在组织结构上也是一个双向链表,只是增加了一个成员变量,表明在此就绪进程队列中的最大执行时间片。而且在进程控制块proc_struct中增加了一个成员变量time_slice,用来记录进程当前的可运行时间片段。这是由于RR调度算法需要考虑执行进程的运行时间不能太长。在每个timer到时的时候,操作系统会递减当前执行进程的time_slice,当time_slice为0时,就意味着这个进程运行了一段时间(这个时间片段称为进程的时间片),需要把CPU让给其他进程执行,于是操作系统就需要让此进程重新回到rq的队列尾,且重置此进程的时间片为就绪队列的成员变量最大时间片max_time_slice值,然后再从rq的队列头取出一个新的进程执行。
Round Robin算法主要实现在schedule/default_sched.c中,我们逐个进行分析。
RR_init
static void
RR_init(struct run_queue *rq) {
list_init(&(rq->run_list));
rq->proc_num = 0;
}
比较简单,用于对进程队列进行初始化。
RR_enqueue
static void
RR_enqueue(struct run_queue *rq, struct proc_struct *proc) {
assert(list_empty(&(proc->run_link)));
list_add_before(&(rq->run_list), &(proc->run_link));
if (proc->time_slice == 0 || proc->time_slice > rq->max_time_slice) {
proc->time_slice = rq->max_time_slice;
}
proc->rq = rq;
rq->proc_num ++;
}
这是一个进程入队的操作:进程队列是一个双向链表,一个进程加入队列的时候,会将其加到队尾,如果进程控制块的时间片为0或者进程的时间片大于分配给进程的最大时间片,则把它重置为max_time_slice,并更新队列的进程数量。
RR_dequeue
static void
RR_dequeue(struct run_queue *rq, struct proc_struct *proc) {
assert(!list_empty(&(proc->run_link)) && proc->rq == rq);
list_del_init(&(proc->run_link));
rq
ucore lab6:RR与Stride调度算法实现

本文介绍了ucore操作系统实验中涉及的两种调度算法:Round Robin和Stride Scheduling。在练习1中,分析了Round Robin调度算法的原理和ucore中的实现,包括进程时间片管理和队列操作。在练习2中,详细解释了Stride Scheduling的机制,它通过进程的Pass值来决定资源分配,确保比例公平。文章提供了相关代码和测试结果,总结了这两种调度算法的理解与实现过程。
最低0.47元/天 解锁文章
531

被折叠的 条评论
为什么被折叠?



