有效的软件调度

Effective software scheduling

例如下面的代码

while(1){
  task1();
  task2();
}

task1() 和 task2() 之间应该有合作,以 rr 方式执行。但是,如果task1()实现如下

task1(){
  while(1);
}

有没有一种方法可以构建一个调度程序,仅依靠软件(例如每 500 毫秒切换一次任务)来避免 task1() 独占资源?

假设只有普通的 C/Assembly,而不依赖于外部 scheduler/OS。

Is there a way to build a scheduler which avoid monopolization of resources by task1() by only relying on software (for example switching tasks each 500 ms)?

是的,这是可能的;但是在纯 C 中可能是不可能的,因为(至少)你需要在任务切换期间在不同的堆栈之间切换。

不过要知道,仅仅每500毫秒切换一次任务就很"not effective"了。具体来说;当一个任务必须等待任何事情时(时间延迟、从网络接收的数据、用户输入、从磁盘获取的数据、互斥量,...)你想通过切换到另一个任务来保持 CPU 忙碌任务(如果还有其他任务)。

这样做;你要么需要所有东西的完全异步接口(C 没有),要么你需要控制所有代码(例如写一个 OS)。

当然大部分的任务切换都是"task has to wait for something"或者"something task was waiting for occurred"造成的;并且每 500 毫秒切换一次任务是相对不相关的(它只对不执行任何 IO 的罕见任务很重要),即使它是相关的也是一个坏主意(在“10 个半完成的工作与 5 个完成的工作和 5未开始的工作”方式)。

一个简单的方法是使用

  1. 一个硬件定时器,
  2. 运行、
  3. 的任务队列
  4. 一个调度器
  5. 和调度员。
  6. 为每个任务预分配堆栈

定时器中断处理程序触发调度程序。调度程序确定下一个 运行 的任务。调度程序触发调度程序。 调度程序在 运行ning 之前的任务和 运行 的下一个任务之间执行 'context' 切换,将之前的 运行ning 任务放回队列中,然后恢复 'context' 的下一个任务到 运行,然后 将执行控制转移到 'next' 任务,

队列由控制块组成。控制块包含所有寄存器的副本和任务入口点的地址