AbStract
In this paper.diferences in task scheduling mechanism between the two multi-tasks operating systems Linux and Vx。
Works are analyzed.The two are compared with aspects of task control block,the standard of scheduling and the policy of
scheduling.Further more.The implementati***** of task scheduling in POSIX 1003.1b specification are analyzed both in Linux
and VxWorks.
Keywords:Linux.VxWorks.task scheduling,scheduling policy,priority
摘要
分析了Linux和VxWorks两种多任务操作系统任务调度机制的异同,从任务控制块、调度的时机、调度的优先级和调度
的策略方面进行了详细的分析和对比。分析了VxWorks和Linux在POSIX1003.1b调度标准实现上的差异。
关键词:Linux.VxWorks,任务调度,调度策略,优先级
通用的分时操作系统面向多用户的不同任务,意在追求系统整体运行的效率和资源的均衡利用,软件的执行在时间上要求并不严格。实时操作系统不同于分时操作系统,它主要是对任务进行实时的处理,要求任务的运行具有可确定性和可预测性,提供即时响应和高可靠性。由此导致通用分时系统和实时操作系统的内核在任务调度机制方面的不同。本文以Linux(2.4)版本内核)和VxWorks(5.4版本)为代表,着重分析二者任务调度机制的异同。
1 进程(任务)控制块
进程是一个具有独立功能的程序对某个数据集在处理机上的执行过程和分配资源的基本单位。进程是一个动态概念,具有并行特征,表现为独立性和异步性。在Linux中,进程和任务的概念是等价的。VxWorks中把每个相互独立的程序称为任务,任务是VxWorks资源分配的单位,也是处理器调度的基本单位。
每个任务拥有各自的上下文,即拥有各自的CPU环境和系统资源。上下文切换时,Linux进程上下文保存在进程控制块中(PCB)中,VxWorks任务的上下文保存在任务控制块(TCB)中,二者的上下文内容有很大的区别。
作为通用操作系统的Linux,其进程所使用(管理)的资源比嵌入式实时操作系统VxWorks要多的多,就任务控制块来说,二者的差异还是比较大的,典型的区别分析如下:
1)多用户性。Linux是多用户操作系统,它使用用户和组标识符来控制进程对系统中文件和映像以及其他资源的访问权限。task_struct中有四对进程和组标识符:进程uid和gid、有效uid和gid、文件系统uid和gid、保留的uid和gid。而VxWorks是单用户的操作系统,任务控制块结构windTcb中没有与用户相关联的数据结构。
2)文件打开表。Linux的每个进程都拥有一个文件打开表,以记录该进程使用文件的情况, 对应于task_struct中file_ struct 类型的files成员。当进程退出时,内核会自动检查并关闭进程已打开但未显式调用close()关闭的文件。VxWorks的整个系统共用一个文件打开表,每个任务控制块中没有记录该任务已打开的文件信息,因此当某个任务退出时,其已打开的文件自然不会被自动关闭。
3)任务之间的亲属性。Linux的每个进程都不是孤立地存在于系统中,新的进程白创建起就置于一种表示“宗族”和“家谱”的树型组织中,初始化进程init是所有进程的祖先进程。在task_ struct结构中有一组task_struct 类型的指针结构成员,其中P_opptr和P_pptr指向父进程,p_cptr指向最“年轻”的子进程,P_Ysptr和P_osptr则分别指向其“哥哥”和“弟弟”。而Vx-Works的任务间没有类似的亲属关系,每一个任务都是平等而独立的,即使一个任务创建并激活一个新的任务,两者之间也不存在父子关系。
另外,Linux的进程控制块和VxWorks任务控制块的差别还有许多,比如Linux的task_struct中保存的进程杂凑队列的链人指针、线程信息、虚拟内存信息等。
2.1 VxWorks的任务调度
2.1.1 VxWorks任务调度时机
VxWorks中任务调度的时机可分以下两种情况:
1)同步任务切换,引起的原因是当前运行的任务执行下列操作:①进行阻塞、延迟、挂起的调用;②使更高优先级任务就绪而发生优先级抢占;③降低自身优先级或者退出。
2)异步任务切换,通常由中断服务使高优先级任务就绪引起。VxWorks的Wind微内核基于优先级抢占调度。并采取单一实地址空间模式,上述引发任务调度的情况发生时,VxWorks内核立即进行任务的调度切换。
2.1.2 VxWorks任务调度策略
多任务运行时需要一个调度算法,将CPU分配给就绪的任务。Wind内核默认采用基于优先级的抢占式调度(Priority-based preemptive scheduling)算法,同时也可以选用轮转(Round-robin)调度算法。
1)基于优先级抢占的任务调度:指每个进程被赋予一个优先级,优先级最高的就绪进程率先执行 可抢占调度(preemptive scheduling)是指允许将逻辑上可运行的进程暂时挂起的策略。VxWorks采用基于优先级抢占的调度算法,系统中的每个任务都拥有一个优先级,内核将CPU分配给处于就绪状态的优先级最高的任务。如果系统内核一旦发现有一个优先级比当前任务的优先级高的任务转变到就绪状态,内核立即保存当前任务的上下文,当前任务状态切换到就绪状态并按优先级插入到相应任务队列的队尾,然后内核切换到这个高优先级任务的上下文中执行。
Wind内核有256个优先级,编号是0-255,0的优先级最高,255最低。任务的优先级可以在创建时设定,系统默认的任务优先级为100。VxWorks允许任务动态改变自己的优先级,当任务执行时,它可以调用taskPrioritySet()改变自己的优先级。
2)轮转调度:VxWorks中,基于优先级抢占的调度可以与轮转调度相结合。轮转调度算法试图让优先级相同的、处于就绪状态的任务公平地分享使用CPU资源。如果不使用轮转调度,当系统中存在多个相同优先级的任务时,第一个获得CPU的任务将会独占CPU,如果没有阻塞或其它情况出现,其它相同优先级的任务将得不到运行的机会。
使用轮转调度时,每个任务被分配一个时间段,称作它的时间片(quantum),即该任务允许运行的时间。在VxWorks系统中,可以调用函数kernelTimeSlice0来选用轮转调度策略,其参数是时间片的长度,该时间片是每一个任务在放弃CPU给另一个相同优先级任务之前,系统允许它运行的时间长度。如果任务在它的时间片中被高优先级的任务抢占,调度器保存它的运行时间计数器,当它再一次符合执行条件的时候,调度器恢复运行时间计数器。
2.1.3 抢占上锁与中断上锁
由于所有VxWorks任务共存于单一的线性地址空间,当多个任务共享全局的数据结构时,需要提供对临界区的互斥访问机制。使用信号量对资源上锁是一种比较通用的互斥手段,如POSIX有名信号灯或无名信号灯和System V的信号量集。VxWorks提供了三种类型的信号量:二进制信号量、互斥信号量和计数器信号量。此外,VxWorks在任务调度层次上提供了互斥访问保护的机制:在I临界区内禁止任务的抢占调度,这在VxWorks中称为抢占上锁,具体互斥的实现是将临界区代码包括在两个函数taskLock()和taskUnlock()之间。
在VxWorks中,不仅任务与任务之间需要考虑互斥,同时任务与中断之间也要考虑互斥。因为中断的优先级高于任何任务,所以抢占上锁虽然保证了任务与任务间的互斥,但并没有保证任务与中断服务程序对I临界区的互斥访问。VxWorks的中断上锁则提供了最强有力的互斥,将临界区代码保护在intLock()和intUnlock()两个函数之间。中断上锁实现的是中断级互斥,在互斥期间,即使外部事件产生而引发相应的中断,系统也不会切换到相应的中断服务程序(iSR)。
因此,VxWorks的抢占上锁和中断上锁是通过禁止任务抢占或禁止切换到中断服务程序来保护临界区的。同时,这种灵活的互斥手段在临界区中也会影响VxWorks任务的原始调度原则,比如低优先级任务抢占上锁时,就绪任务队列上具有较高优先级的任务却不能即时占有处理机。
2.2 Linux的进程调度
2.2.1 Linux进程调度的时机
Linux进程的调度时机大致分为两种情况:一种是进程自愿调度;另一种是发生强制性调度。首先,自愿的调度随时都可以进行。在内核空间中,进程可以通过schedule()启动一次调度;在用户空间中,可以通过系统调用pause()达到同样的目的。如果要为自愿的暂停行为加上时间限制,在内核中使用schedule_timeout(),而在用户空间则使用nanosleep()系统调用。Linux中,强制性的调度发生在每次从系统调用返回的前夕,以及每次中断或异常处理返回用户空间的前夕。应注意的是,从内核态返回到用户态是进程调度发生的必要条件,而不是充分条件,还要取决于当前进程task_struct结构中的need_resched是否为1。单CPU条件下,有三种情况可以使当始终比所有的非实时进程都要大,这就保证了实时进程的优先运行。实时进程的counter与nice都与其优先级权值无关,这和普通进程是有区别的, 实时进程task_struct中的nice和counter只与SCHED—RR调度策略进程的时间片计数相关;而对于SCHED—FIFO调度策略的实时进程没有调度的参考意义。
3 POSlX调度接口
POSIX1003.1b实时扩展标准定义了进程调度的标准函数接El形式,VxWorks的任务调度和Linux中实时进程的调度都支持POSIX1003.1b标准,但二者在该标准的实现上差异较大,列出如下。
1)实时优先级数。VxWorks任务的优先级为0-255,Wind内核默认为数值越大,任务优先级越低。Unux实时进程优先级为1~99,数值越大,进程优先级越高。
2)调度策略的种类。Linux支持SCHED—RR、SCHED—FIFO和SCHED—OTHER的调度策略,而VxWorks只支持前两种策略,不支持SCHED_OTHER策略。另外Linux实时进程和普通进程可以互相转换, 通过SCHED_OTHER 参数调用sched_ setscheduler()函数,可以将Linux实时进程转化为普通进程。通过以SCHEDl-RR或SCHED FIFO 为参数调用sched_ setscheduler()也可以将普通进程转为实时进程。
3)调度策略所基于的对象。VxWorks的任务调度策略不是基于某个任务的,而是针对整个系统的所有任务。VxWorks下不能通过sched—setscheduler()来改变内核当前的任务调度策略,VxWorks下改变调度策略的唯一手段是通过kernelTimeSlice()函数设置轮转调度的时间片长度来实现的,该时间片长度设为0时。即取消了SCHED—RR策略。Linux中的调度策略是基于进程的,某个进程调度策略的设置不影响其他进程。
4 结束语
VxWorks作为嵌入式实时操作系统,Linux作为通用分时操作系统,二者在任务调度机制方面差异较大,包括任务上下文内容、任务的优先级、调度的时机、调度的策略等。二者在兼容POSI×10o3.1b进程调度标准的同时其具体实现又有差异。本文通过分析与比较Linux和VxWorks任务(进程)调度机制的异同,有助于理解实时内核和通用分时内核在任务调度机制实现层次上的差异,并基于它们更有针对性地开发相应的应用,同时对基于通用操作系统Linux的一些实时化改造工作也提供参
考借鉴作用。
参考文献
张尧学,史美林.计算机操作系统教程(第2版).清华大学出版社,2OO1
李方敏.VxWorks高级程序设计.清华大学出版社,2004
Andrew S.Tanenbaum.现代操作系统.机械工业出版社,2000
代玲莉,欧阳劲.Linux内核分析与实例应用 国防工业出版社,20o2
毛德操,胡希明.Linux内核源代码情景分析.浙江大学出版社,2001
In this paper.diferences in task scheduling mechanism between the two multi-tasks operating systems Linux and Vx。
Works are analyzed.The two are compared with aspects of task control block,the standard of scheduling and the policy of
scheduling.Further more.The implementati***** of task scheduling in POSIX 1003.1b specification are analyzed both in Linux
and VxWorks.
Keywords:Linux.VxWorks.task scheduling,scheduling policy,priority
摘要
分析了Linux和VxWorks两种多任务操作系统任务调度机制的异同,从任务控制块、调度的时机、调度的优先级和调度
的策略方面进行了详细的分析和对比。分析了VxWorks和Linux在POSIX1003.1b调度标准实现上的差异。
关键词:Linux.VxWorks,任务调度,调度策略,优先级
通用的分时操作系统面向多用户的不同任务,意在追求系统整体运行的效率和资源的均衡利用,软件的执行在时间上要求并不严格。实时操作系统不同于分时操作系统,它主要是对任务进行实时的处理,要求任务的运行具有可确定性和可预测性,提供即时响应和高可靠性。由此导致通用分时系统和实时操作系统的内核在任务调度机制方面的不同。本文以Linux(2.4)版本内核)和VxWorks(5.4版本)为代表,着重分析二者任务调度机制的异同。
1 进程(任务)控制块
进程是一个具有独立功能的程序对某个数据集在处理机上的执行过程和分配资源的基本单位。进程是一个动态概念,具有并行特征,表现为独立性和异步性。在Linux中,进程和任务的概念是等价的。VxWorks中把每个相互独立的程序称为任务,任务是VxWorks资源分配的单位,也是处理器调度的基本单位。
每个任务拥有各自的上下文,即拥有各自的CPU环境和系统资源。上下文切换时,Linux进程上下文保存在进程控制块中(PCB)中,VxWorks任务的上下文保存在任务控制块(TCB)中,二者的上下文内容有很大的区别。
作为通用操作系统的Linux,其进程所使用(管理)的资源比嵌入式实时操作系统VxWorks要多的多,就任务控制块来说,二者的差异还是比较大的,典型的区别分析如下:
1)多用户性。Linux是多用户操作系统,它使用用户和组标识符来控制进程对系统中文件和映像以及其他资源的访问权限。task_struct中有四对进程和组标识符:进程uid和gid、有效uid和gid、文件系统uid和gid、保留的uid和gid。而VxWorks是单用户的操作系统,任务控制块结构windTcb中没有与用户相关联的数据结构。
2)文件打开表。Linux的每个进程都拥有一个文件打开表,以记录该进程使用文件的情况, 对应于task_struct中file_ struct 类型的files成员。当进程退出时,内核会自动检查并关闭进程已打开但未显式调用close()关闭的文件。VxWorks的整个系统共用一个文件打开表,每个任务控制块中没有记录该任务已打开的文件信息,因此当某个任务退出时,其已打开的文件自然不会被自动关闭。
3)任务之间的亲属性。Linux的每个进程都不是孤立地存在于系统中,新的进程白创建起就置于一种表示“宗族”和“家谱”的树型组织中,初始化进程init是所有进程的祖先进程。在task_ struct结构中有一组task_struct 类型的指针结构成员,其中P_opptr和P_pptr指向父进程,p_cptr指向最“年轻”的子进程,P_Ysptr和P_osptr则分别指向其“哥哥”和“弟弟”。而Vx-Works的任务间没有类似的亲属关系,每一个任务都是平等而独立的,即使一个任务创建并激活一个新的任务,两者之间也不存在父子关系。
另外,Linux的进程控制块和VxWorks任务控制块的差别还有许多,比如Linux的task_struct中保存的进程杂凑队列的链人指针、线程信息、虚拟内存信息等。
2.1 VxWorks的任务调度
2.1.1 VxWorks任务调度时机
VxWorks中任务调度的时机可分以下两种情况:
1)同步任务切换,引起的原因是当前运行的任务执行下列操作:①进行阻塞、延迟、挂起的调用;②使更高优先级任务就绪而发生优先级抢占;③降低自身优先级或者退出。
2)异步任务切换,通常由中断服务使高优先级任务就绪引起。VxWorks的Wind微内核基于优先级抢占调度。并采取单一实地址空间模式,上述引发任务调度的情况发生时,VxWorks内核立即进行任务的调度切换。
2.1.2 VxWorks任务调度策略
多任务运行时需要一个调度算法,将CPU分配给就绪的任务。Wind内核默认采用基于优先级的抢占式调度(Priority-based preemptive scheduling)算法,同时也可以选用轮转(Round-robin)调度算法。
1)基于优先级抢占的任务调度:指每个进程被赋予一个优先级,优先级最高的就绪进程率先执行 可抢占调度(preemptive scheduling)是指允许将逻辑上可运行的进程暂时挂起的策略。VxWorks采用基于优先级抢占的调度算法,系统中的每个任务都拥有一个优先级,内核将CPU分配给处于就绪状态的优先级最高的任务。如果系统内核一旦发现有一个优先级比当前任务的优先级高的任务转变到就绪状态,内核立即保存当前任务的上下文,当前任务状态切换到就绪状态并按优先级插入到相应任务队列的队尾,然后内核切换到这个高优先级任务的上下文中执行。
Wind内核有256个优先级,编号是0-255,0的优先级最高,255最低。任务的优先级可以在创建时设定,系统默认的任务优先级为100。VxWorks允许任务动态改变自己的优先级,当任务执行时,它可以调用taskPrioritySet()改变自己的优先级。
2)轮转调度:VxWorks中,基于优先级抢占的调度可以与轮转调度相结合。轮转调度算法试图让优先级相同的、处于就绪状态的任务公平地分享使用CPU资源。如果不使用轮转调度,当系统中存在多个相同优先级的任务时,第一个获得CPU的任务将会独占CPU,如果没有阻塞或其它情况出现,其它相同优先级的任务将得不到运行的机会。
使用轮转调度时,每个任务被分配一个时间段,称作它的时间片(quantum),即该任务允许运行的时间。在VxWorks系统中,可以调用函数kernelTimeSlice0来选用轮转调度策略,其参数是时间片的长度,该时间片是每一个任务在放弃CPU给另一个相同优先级任务之前,系统允许它运行的时间长度。如果任务在它的时间片中被高优先级的任务抢占,调度器保存它的运行时间计数器,当它再一次符合执行条件的时候,调度器恢复运行时间计数器。
2.1.3 抢占上锁与中断上锁
由于所有VxWorks任务共存于单一的线性地址空间,当多个任务共享全局的数据结构时,需要提供对临界区的互斥访问机制。使用信号量对资源上锁是一种比较通用的互斥手段,如POSIX有名信号灯或无名信号灯和System V的信号量集。VxWorks提供了三种类型的信号量:二进制信号量、互斥信号量和计数器信号量。此外,VxWorks在任务调度层次上提供了互斥访问保护的机制:在I临界区内禁止任务的抢占调度,这在VxWorks中称为抢占上锁,具体互斥的实现是将临界区代码包括在两个函数taskLock()和taskUnlock()之间。
在VxWorks中,不仅任务与任务之间需要考虑互斥,同时任务与中断之间也要考虑互斥。因为中断的优先级高于任何任务,所以抢占上锁虽然保证了任务与任务间的互斥,但并没有保证任务与中断服务程序对I临界区的互斥访问。VxWorks的中断上锁则提供了最强有力的互斥,将临界区代码保护在intLock()和intUnlock()两个函数之间。中断上锁实现的是中断级互斥,在互斥期间,即使外部事件产生而引发相应的中断,系统也不会切换到相应的中断服务程序(iSR)。
因此,VxWorks的抢占上锁和中断上锁是通过禁止任务抢占或禁止切换到中断服务程序来保护临界区的。同时,这种灵活的互斥手段在临界区中也会影响VxWorks任务的原始调度原则,比如低优先级任务抢占上锁时,就绪任务队列上具有较高优先级的任务却不能即时占有处理机。
2.2 Linux的进程调度
2.2.1 Linux进程调度的时机
Linux进程的调度时机大致分为两种情况:一种是进程自愿调度;另一种是发生强制性调度。首先,自愿的调度随时都可以进行。在内核空间中,进程可以通过schedule()启动一次调度;在用户空间中,可以通过系统调用pause()达到同样的目的。如果要为自愿的暂停行为加上时间限制,在内核中使用schedule_timeout(),而在用户空间则使用nanosleep()系统调用。Linux中,强制性的调度发生在每次从系统调用返回的前夕,以及每次中断或异常处理返回用户空间的前夕。应注意的是,从内核态返回到用户态是进程调度发生的必要条件,而不是充分条件,还要取决于当前进程task_struct结构中的need_resched是否为1。单CPU条件下,有三种情况可以使当始终比所有的非实时进程都要大,这就保证了实时进程的优先运行。实时进程的counter与nice都与其优先级权值无关,这和普通进程是有区别的, 实时进程task_struct中的nice和counter只与SCHED—RR调度策略进程的时间片计数相关;而对于SCHED—FIFO调度策略的实时进程没有调度的参考意义。
3 POSlX调度接口
POSIX1003.1b实时扩展标准定义了进程调度的标准函数接El形式,VxWorks的任务调度和Linux中实时进程的调度都支持POSIX1003.1b标准,但二者在该标准的实现上差异较大,列出如下。
1)实时优先级数。VxWorks任务的优先级为0-255,Wind内核默认为数值越大,任务优先级越低。Unux实时进程优先级为1~99,数值越大,进程优先级越高。
2)调度策略的种类。Linux支持SCHED—RR、SCHED—FIFO和SCHED—OTHER的调度策略,而VxWorks只支持前两种策略,不支持SCHED_OTHER策略。另外Linux实时进程和普通进程可以互相转换, 通过SCHED_OTHER 参数调用sched_ setscheduler()函数,可以将Linux实时进程转化为普通进程。通过以SCHEDl-RR或SCHED FIFO 为参数调用sched_ setscheduler()也可以将普通进程转为实时进程。
3)调度策略所基于的对象。VxWorks的任务调度策略不是基于某个任务的,而是针对整个系统的所有任务。VxWorks下不能通过sched—setscheduler()来改变内核当前的任务调度策略,VxWorks下改变调度策略的唯一手段是通过kernelTimeSlice()函数设置轮转调度的时间片长度来实现的,该时间片长度设为0时。即取消了SCHED—RR策略。Linux中的调度策略是基于进程的,某个进程调度策略的设置不影响其他进程。
4 结束语
VxWorks作为嵌入式实时操作系统,Linux作为通用分时操作系统,二者在任务调度机制方面差异较大,包括任务上下文内容、任务的优先级、调度的时机、调度的策略等。二者在兼容POSI×10o3.1b进程调度标准的同时其具体实现又有差异。本文通过分析与比较Linux和VxWorks任务(进程)调度机制的异同,有助于理解实时内核和通用分时内核在任务调度机制实现层次上的差异,并基于它们更有针对性地开发相应的应用,同时对基于通用操作系统Linux的一些实时化改造工作也提供参
考借鉴作用。
参考文献
张尧学,史美林.计算机操作系统教程(第2版).清华大学出版社,2OO1
李方敏.VxWorks高级程序设计.清华大学出版社,2004
Andrew S.Tanenbaum.现代操作系统.机械工业出版社,2000
代玲莉,欧阳劲.Linux内核分析与实例应用 国防工业出版社,20o2
毛德操,胡希明.Linux内核源代码情景分析.浙江大学出版社,2001