调度器

目录

什么是调度器

分类

合作调度器

抢占式调度器

混合式调度器


什么是调度器

 

  • 首先调度器可以看作是一个简单的操作系统,允许以周期性或单次方式调度任务。
  • 从底层看,调度器实则是一个多个不同任务共享的定时器中断服务程序。
  • 调度器分为:合作调度器、抢占调度器和混合调度器。
  • 所有的实时操作系统都有一个调度器。

分类

  • 合作调度器(不可剥夺型调度器)
  • 抢占式调度器(可剥型调度器)
  • 混合式调度器

合作调度器

 

合作调度器提供的是一种单任务的系统结构,可靠可预测性原因就是因为在任何时刻只有一个任务运行直到运行完成,然后运行的次数与时间有调度器控制。

  • 任务在设定的时刻以周期性或单次运行方式被被调度执行。
  • 当任务需要运行时,需添加到任务队列等待。
  • 当CPU空闲时,运行等待任务队列中的下一个任务(如果有的话)。
  • 这种调度器非常简单,只需少量代码即可实现。
  • 调度程序一次只能为一个任务分配内存。
  • 该调度器有全部有C语言实现。

抢占式调度器

抢占式调度器会为每个任务都分配一个优先级,调度器会激活就绪任务中优先级最高的任务。抢占式调度器给任务带来快速响应的同时也使得任务间的同步和通信机制显的很麻烦,而且源码中的很多地方都需要设置临界段(通过开关中断来实现)。

抢占式调度器提供了一种多任务的系统结构。

操作:

  • 任务在特定的时刻被调度运行(以周期性或者单次方式)
  • 当任务需要运行的时候,被添加到等待队列。
  • 等待的任务(如果有的话)运行一段固定的时间,如果没有完成,将被放回到等待队列。然后下一个等待任务将会运行一段固定的时间,以此类推。

实现:

  •  这种调度器相对复杂,访问共享资源时,要防止冲突。
  • 该调度器必须为强占任务的所有中间状态分配存储器。
  • 该调度器通常将(至少部分)由汇编语言编写。
  • 该调度器通常作为一个独立的系统被创建。

性能:

  • 对外部事件的响应速度快。

可靠性和安全性:

  • 与合作式任务相比,通常认为更不可预测,并且可靠性低。 

使用抢占式调度器最大的好处是对外部事件的快速响应,提高系统的实时性。带来好处的同时也是要付出代价的,下面就举一个例子,这个例子比较典型。

假设系统中的一个任务要从 ADC 端口读取模拟信号,这时发生了上下文切换,另一个任务也要访问这个端口,在这种情况下如果不采取措施阻止这种情况,数据将可能丢失或者破坏。这种问题往往出现在多任务平台中所谓的“临界段”,这些代码段一旦开始就必须不中断地运行,直到跑完这段代码。临界段还有很多,比如:

  •  读取或者修改变量(特别是任务间通信的全局变量)的代码,一般来说这时最常见的关键代码。
  • 如果读过μCOS-II 或μCOS-III 源代码的话,会发现里面很多地方都做了开关中断的处理,就是为了防止多任务造成错误。
  • 调用公共函数的代码,特别是不可重入的函数,如果多个任务都访问这个函数,结果是可想而知的。

解决这种情况最常用的的办法就是在临界段做开关中断处理,这种情况是最影响实时性的,如果关中断期间发生了外部中断事件,那么这个中断事件只有临界段执行完之后才能得到相应。还有一种解决办法就是使用调度锁,这样在一定程度上能够提供任务的实时性,在发生外部中断的时候会得到相应,但是不会发生任务切换,必须等到调度锁被解开。

关于抢占式调度器和合作式调度器到底谁好,在嵌入式领域没有一个定论,要根据自己的时间应用选择,很多嵌入式领域的专家都发表过这方面的文章,有兴趣的可以找找深入研究下,下面是 Michael J. Pont的观点,原话如下: 

Finally, it should be noted that the reasons why pre-emptive schedulers have been morewidely discussed and used may not be for technical reasons at all: in fact, the use of pre-emptive environments can be seen to have clear commercial advantages for some companies. For example, a co-operative scheduler may be easily constructed, entirely in a high-level programming language, in around 300 lines of ‘C’ code, as we demonstrate in Chapter 9. The code is highly portable, easy to understand and to use and is, in effect, freely available. By contrast, the increased complexity of a preemptive operating environment results in a much larger code framework (some ten times the size, even in a simple implementation: Labrosse, 1998). The size and complexity of this code makes it unsuitable for ‘in-house’ construction in most situations and therefore provides the basis for a commercial ‘RTOS’ products to be sold, generally at high prices and often with expensive run-time royalties to be paid. The continued promotion and sale of such environments has, in turn, prompted further academic interest in thisarea.

上面这段话的意思是说,抢占式调度器被广泛的讨论和使用的原因可能并不完全是技术上的问题,实际上对于一些公司来说,使用抢占式平台有明显的商业上的好处,这个该怎么理解呢?比如我们做了一款产品,产品的系统是用的μCOS-II。我们肯定会在说明书中宣称我们使用的是μCOS-II 系统,因为这个系统已经得到了业界的认可,而不会使用我们自己的设计的系统,用户在购买产品的时候肯定会首选用 μCOS-II 设计的系统。如果使用合作式调度器,只需要 300 行左右的 C 代码就可以实现一个合作式调度器,这些代码的可移植性非常好,易于理解和使用,并且实际上是免费使用的。相比而言,抢占式运行环境增加了复杂性,从而导致更复杂的代码结构。在大多数情况下,这些代码的复杂性和长度使其不适合于普通开发人员自己构建,因此提供了商业实时操作系统的产品的销售基础。抢占式调度器通常价格比较贵,而且还需占用很大的实时开销。这些平台持续不断的宣称和销售反过来又促进了这个领域的更进一步的学术研究。 

混合式调度器

合作式调度器为各种嵌入式系统提供了一个可预测的平台。在一些场合可能需要在合作式调度器结构中加入抢占式调度器的一些特性,并小心的加以控制,混合式调度器应运而生。

混合式调度器综合了合作式调度器和抢占式调度器的特性,而且这种方式始终是受控的,不依赖复杂的上下文切换程序,以及任务间复杂的通信机制。下面是混合式调度器的特性:混合式调度器

混合式调度器提供了有限的多任务处理能力。

操作:

  • 支持多个合作式调度的任务。
  •  支持一个抢占式任务(可以中断合作式任务)。

实现:

  •  这种调度器很简单,用少量代码即可实现。
  • 该调度器必须同时为两个任务分配存储器。
  • 该调度器通常完全由高级语言(比如”C”实现)。
  • 该调度器不是一种独立的系统,它成为开发人员的代码的一部分。

性能:

  •  对外部事件的响应速度快

可靠性和安全性:

  • 只要小心设计可以和纯碎的合作式调度器一样可靠。 

 

这里所描述的混合式调度器和合作式调度器是有区别的,区别如下:

  • 不再要求所有任务都在时标间隔之间完成任务。一个(或者更多)的合作式任务的运行时间可以大于时标间隔。
  • 与前面讨论的合作式调度器一样,可以调度任意个合作式任务。然而,还可以同时调度一个抢占式任务。 
  • 抢占式任务可以抢先(中断)合作式任务。
  • 一旦抢占式任务开始运行,将一直运行到完成。

同时注意:

与完全的抢占式解决方案相比,只有一个抢占式任务,而且该任务连续运行直到完成,这将及大地简化系统的结构。尤其是不需要实现上下文切换的机制。这意味着: 该结构仍然十分简单。 运行环境可以全部由 C 实现。和完全的抢占式调度器相比,简化了任务间的通信。 应该只有一个短任务(最长的运行时间大于为时标间隔的%50,尽可能的短)可以强占运行,否则将削弱系统的整体性能。

你可能感兴趣的:(嵌入式)