进程优先级
1.简介
我们有了进程调度 目前来看 所有进程一律平等
我们的调度算法是遍历每一个进程 然后给每一个进程一定的运行时间
然后再切换下一个进程
但实际运用上 进程间不会是平等的 有些进程承担着比较重要的工作
因此 它有理由获得更多的运行时间
例如内核进程 一些进程不是很重要
它就不应该占用过度的CPU资源
本节 我们要引入进程优先级的功能 让优先级高的进程获得更多的运行机会
2.代码
首先我们需要改动的是对TASK结构体的定义(multi_task.h)
struct TASK { int sel, flags; int priority; struct TSS32 tss; };
我们增加了一个变量叫priority 这个变量代表着进程的优先级
同时也是进程运行的时间片 这个值越大 进程获得的CPU运行时间就越多
TASK对象的相关处理函数也需要做相应改动 在multi_task.c中
struct TASK *task_init(struct MEMMAN *memman) { .... task = task_alloc(); task->flags = 2; //active task->priority = 100; taskctl->running = 1; taskctl->now = 0; taskctl->tasks[0] = task; load_tr(task->sel); task_timer = timer_alloc(); timer_settime(task_timer, task->priority); return task; .... } void task_run(struct TASK *task, int priority) { if (priority > 0) { task->priority = priority; } task->flags = 2; taskctl->tasks[taskctl->running] = task; taskctl->running++; return; } void task_switch(void) { struct TASK *task; if (taskctl->running >= 2) { taskctl->now++; if (taskctl->now == taskctl->running) { taskctl->now = 0; } task = taskctl->tasks[taskctl->now]; timer_settime(task_timer, task->priority); farjmp(0, taskctl->tasks[taskctl->now]->sel); } return; }
每个任务分配时 它的优先级会默认设置成100 也就是该任务能获得1秒的运行时间
task_run 多增加了一个参数 也就是任务优先级
当一个任务准备加入调度队列时 需要指定它的优先级
在task_switch中 任务切换时
我们通过timer_settime来设置任务的运行时间
大家可以看到 时钟的长度设置为task->priority 也就是说 任务的优先级同时也是任务的CPU运行时间
任务激活的相关代码也需要做改动 任务可以对应一个数据队列
当队列有数据抵达时 队列会把存储在其中的任务加入调度队列
这个功能的实现是在golobal_define.c中
因此 我们也需要做相应改动
int fifo8_put(struct FIFO8 *fifo, unsigned char data) { .... if (fifo->task != 0) { if (fifo->task->flags != 2) { task_run(fifo->task, 0); } } .... }
当任务重新被激活时 我们传入的优先级数值是0
根据task_run的实现 当优先级数值为0时 任务保持原有优先级不变
最后需要改动的是主入口函数 在write_vga_desktop.c中
void CMain(void) { .... for (i = 0; i < 2; i++) { .... task_run(task_b[i], (i+1)*5); ... } .... }
我们为第一个任务分配的优先级是5
第二个任务的优先级是10
也就是第二个任务得到的CPU时间是第一个任务的2倍
将上面代码编译运行时可以得到下面结果
3.编译和运行
可以看到 两个小框里的数值
右边的大约是左边的数值的两倍