1 changed files with 69 additions and 0 deletions
@ -0,0 +1,69 @@ |
|||
23回补充内容 by sn: |
|||
|
|||
0.11 的调度函数 schedule,在文件 kernel/sched.c 中定义为: |
|||
|
|||
```c |
|||
while (1) { |
|||
c = -1; next = 0; i = NR_TASKS; p = &task[NR_TASKS]; |
|||
|
|||
// 找到 counter 值最大的就绪态进程 |
|||
while (--i) { |
|||
if (!*--p) continue; |
|||
if ((*p)->state == TASK_RUNNING && (*p)->counter > c) |
|||
c = (*p)->counter, next = i; |
|||
} |
|||
|
|||
// 如果有 counter 值大于 0 的就绪态进程,则退出 |
|||
if (c) break; |
|||
|
|||
// 如果没有: |
|||
// 所有进程的 counter 值除以 2 衰减后再和 priority 值相加, |
|||
// 产生新的时间片 |
|||
for(p = &LAST_TASK ; p > &FIRST_TASK ; --p) |
|||
if (*p) (*p)->counter = ((*p)->counter >> 1) + (*p)->priority; |
|||
} |
|||
|
|||
// 切换到 next 进程 |
|||
switch_to(next); |
|||
``` |
|||
|
|||
|
|||
由上面的程序可以看出,0.11 的调度算法是选取 `counter` 值最大的就绪进程进行调度。 |
|||
当没有 counter 值大于 0 的就绪进程时,要对所有的进程做 `(*p)->counter = ((*p)->counter >> 1) + (*p)->priority`。 |
|||
其效果是对所有的进程(**包括阻塞态进程**)都进行 counter 的衰减,并再累加 priority 值。这样,对正被阻塞的进程来说,其此时的counter不为0,那么计算后得到的counter大于就绪态进程。 |
|||
于是可知,**一个进程在阻塞队列中停留的时间越长,其优先级越大,被分配的时间片也就会越大**。 |
|||
|
|||
|
|||
所以总的来说,Linux 0.11 的进程调度是一种**综合考虑进程优先级并能动态反馈调整时间片的轮转调度算法**。 |
|||
|
|||
|
|||
|
|||
## 进程 counter 是如何初始化的 |
|||
|
|||
首先回答第一个问题,显然这个值是在 fork() 中设定的。Linux 0.11 的 `fork()` 会调用 `copy_process()` 来完成从父进程信息拷贝(所以才称其为 fork),看看 `copy_process()` 的实现,会发现其中有下面两条语句: |
|||
|
|||
```c |
|||
// 用来复制父进程的PCB数据信息,包括 priority 和 counter |
|||
*p = *current; |
|||
|
|||
// 初始化 counter |
|||
p->counter = p->priority; |
|||
// 因为父进程的counter数值已发生变化,而 priority 不会,所以上面的第二句代码将p->counter 设置成 p->priority。 |
|||
// 每个进程的 priority 都是继承自父亲进程的,除非它自己改变优先级。 |
|||
``` |
|||
|
|||
①假设没有改变优先级,时间片的初值就是进程 0 的 priority,即宏 INIT_TASK 中定义的: |
|||
```c |
|||
#define INIT_TASK \ |
|||
{ 0,15,15, |
|||
// 上述三个值分别对应 state、counter 和 priority; |
|||
``` |
|||
|
|||
## 当进程的时间片用完时,被重新赋成何值? |
|||
|
|||
接下来回答第二个问题,当就绪进程的 counter 为 0 时,不会被调度(schedule 要选取 counter 最大的,大于 0 的进程),而当所有的就绪态进程的 counter 都变成 0 时,会执行下面的语句: |
|||
|
|||
```c |
|||
(*p)->counter = ((*p)->counter >> 1) + (*p)->priority; |
|||
``` |
|||
算出的新的 counter 值也等于 priority,即初始时间片的大小。 |
Loading…
Reference in new issue