有效的软件调度
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未开始的工作”方式)。
一个简单的方法是使用
- 一个硬件定时器,
- 运行、
的任务队列
- 一个调度器
- 和调度员。
- 为每个任务预分配堆栈
定时器中断处理程序触发调度程序。调度程序确定下一个 运行 的任务。调度程序触发调度程序。
调度程序在 运行ning 之前的任务和 运行 的下一个任务之间执行 'context' 切换,将之前的 运行ning 任务放回队列中,然后恢复 'context' 的下一个任务到 运行,然后
将执行控制转移到 'next' 任务,
队列由控制块组成。控制块包含所有寄存器的副本和任务入口点的地址
例如下面的代码
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未开始的工作”方式)。
一个简单的方法是使用
- 一个硬件定时器,
- 运行、 的任务队列
- 一个调度器
- 和调度员。
- 为每个任务预分配堆栈
定时器中断处理程序触发调度程序。调度程序确定下一个 运行 的任务。调度程序触发调度程序。 调度程序在 运行ning 之前的任务和 运行 的下一个任务之间执行 'context' 切换,将之前的 运行ning 任务放回队列中,然后恢复 'context' 的下一个任务到 运行,然后 将执行控制转移到 'next' 任务,
队列由控制块组成。控制块包含所有寄存器的副本和任务入口点的地址