【问题标题】:Effective software scheduling有效的软件调度
【发布时间】:2019-12-12 15:36:47
【问题描述】:

例如在下面的代码中

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

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

task1(){
  while(1);
}

有没有办法构建一个调度器,通过仅依赖软件(例如每 500 毫秒切换一次任务)来避免 task1() 垄断资源?

【问题讨论】:

  • 什么处理器?我熟悉 ARM,这当然是可能的。
  • 任何处理器。你能链接一些资源吗?
  • 这就是所谓的抢先式多任务,通常通过使用两个线程进程来实现。
  • 您可以使用 FreeRTOS、Mbed OS 等实时操作系统 (RTOS) 来实现此目的。

标签: c scheduler


【解决方案1】:

有没有办法构建一个调度器,通过仅依赖软件(例如每 500 毫秒切换一次任务)来避免 task1() 垄断资源?

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

不过,你应该知道,仅仅每 500 毫秒切换一次任务是非常“无效”的。具体来说;当一个任务必须等待任何事情(时间延迟、从网络接收的数据、用户输入、要从磁盘获取的数据、互斥锁等)时,您希望通过切换到另一个任务来保持 CPU 忙碌(如果有是任何其他任务)。

要做到这一点;你要么需要所有东西的完全异步接口(C 没有),要么你需要控制所有代码(例如编写一个操作系统)。

当然,大多数任务切换是由“任务必须等待某事”或“某项任务正在等待发生”引起的;并且每 500 毫秒切换一次任务相对无关紧要(它只对不做任何 IO 的稀有任务很重要),即使它是相关的,这也是一个坏主意(在“10 个半完成的工作与 5 个完成的工作和 5 个未开始的工作”方式)。

【讨论】:

  • “在纯 C 中可能不可能”是什么意思?它必须用汇编编写?
  • @FiddlingBits:组装会更容易;但是(理论上,也许;并且非常依赖 C 库并且根本不可移植)您可以使用 C 来生成和管理 jmp_buf env 结构/s,然后使用 (POSIX) setjmp() 和 @ 987654323@为实际任务切换。
【解决方案2】:

一个简单的方法是使用

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

定时器中断处理程序触发调度程序。调度程序确定接下来要运行哪个任务。调度器触发调度器。 调度器在之前运行的任务和下一个要运行的任务之间执行“上下文”切换,将之前运行的任务放回队列中,然后恢复下一个要运行的任务的“上下文”,然后 将执行控制权转移到“下一个”任务,

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

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 2014-04-19
    • 2014-03-19
    • 1970-01-01
    • 2020-08-14
    • 1970-01-01
    相关资源
    最近更新 更多