|
知识路径: > 嵌入式系统软件基础知识 > 嵌入式操作系统基础知识 > 处理器管理 > 分区、进程、线程、任务的概念 >
|
考试要求:掌握
相关知识点:35个
|
|
|
|
|
在多道程序的嵌入式操作系统中,同时存在着多个任务,这些任务之间的结构一般为层状结构,存在着父子关系。当嵌入式内核刚刚启动的时候,只有一个任务存在,然后由该任务派生出所有其他的任务,如下图所示。
|
|
|
|
|
|
在一个嵌入式操作系统当中,任务的创建主要发生在以下三种情形:
|
|
|
(1)系统初始化:当嵌入式内核在进行系统初始化的时候,一般都会创建一些任务。例如,它可能会创建一些前台任务,负责与嵌入式系统的用户进行交互;也可能会创建一些后台任务,这些任务不直接跟用户交互,而是在后台完成一些特定的功能,如键盘扫描、系统状态检测、时间统计等。
|
|
|
(2)任务运行过程中:除了在系统初始化的时候会创建任务以外,当一个任务正在运行的时候,如果需要的话,也能够使用相应的系统调用来创建新的任务,以帮助它完成自己的工作。
|
|
|
(3)用户提出请求:在一些具有交互功能的嵌入式系统中,用户可以通过敲入命令或点击图标的方式,让系统启动一个新的任务。例如,在一个PDA中,用户可以点击某一个游戏,或打开视频播放器,这时系统就会创建相应的任务来满足用户的请求。
|
|
|
虽然在以上的这三种情形下,都能够创建一个新的任务,但是从技术的角度来说,实际上只有一种创建任务的方法,也就是在一个已经存在的任务中,通过调用相应的系统调用函数来创建一个新的任务。
|
|
|
在嵌入式操作系统当中,任务的创建主要有两种可能的实现模型,即fork/exec和spawn,两者既有联系又有区别。
|
|
|
fork/exec模型源于IEEE/ISO POSIX 1003.1标准,而spawn模型是从它派生出来的。这两种模型在创建任务的时候,过程非常相似。首先为新任务分配相应的数据结构,存放其各种管理信息,然后为它分配内存空间,存放任务的代码和数据。当这个新任务准备就绪后,就可以启动其运行。
|
|
|
两种模型的差别主要在于内存的分配方式。在fork/exec模型下,首先调用fork函数为新任务创建一份与父任务完全相同的内存空间,然后再调用exec函数装入新任务的代码,并用它来覆盖原有的属于父任务的内容。这样做的好处是:对于新创建的子任务来说,如果需要的话,它可以从父任务那里继承代码、数据等各种属性。而在spawn模型下,摒弃了继承这一功能,在创建新任务的时候,直接为它分配一个全新的地址空间,然后将新任务的代码装入并运行。
|
|
|
在有些嵌入式系统当中,尤其是一些控制系统,它的某些任务被设计为“死循环”的模式。
|
|
|
|
在多道程序系统中,任务是独立运行的实体,需要参与系统资源的竞争,只有在所需资源都得到满足的情形下,才能在CPU上运行。因此,任务所拥有的资源情况是在不断变化的,这导致任务的状态也表现出不断变化的特性。不同的嵌入式操作系统对任务状态的定义不尽相同,但是一般来说,它们都会具备以下的三种基本状态。
|
|
|
.运行状态(Running):任务占有CPU,并在CPU上运行。显然,处于此状态的任务个数必须小于或等于CPU的数目。如果在系统当中只有一个CPU的话,那么在任何一个时刻,最多只能有一个任务处于运行状态。
|
|
|
.就绪状态(Ready):任务已经具备了运行的条件,但是由于CPU正忙,正在运行其他的任务,所以暂时不能运行。不过,只要把CPU分给它,它就能够立刻执行。
|
|
|
.阻塞状态(Blocked):也叫等待状态(Waiting)。任务因为正在等待某种事件的发生而暂时不能够运行。例如,它正在等待某个I/O操作的完成,或者它跟某个任务之间存在着同步关系,正在等待该任务给它发信号。此时,即使CPU已经空闲下来了,它也还是不能运行。
|
|
|
在一定条件下,任务会在不同的状态之间来回转换,如下图所示。对于任务的三种状态,可以有四种转换关系。
|
|
|
|
|
.运行→阻塞:任务由于等待某个事件而被阻塞起来。例如,一个任务正在CPU上运行,这时它需要用户输入一个字符。由于CPU的运行速度远远高于I/O设备的处理速度,因此操作系统不会允许该任务继续占用CPU,在那里空等,而是把它变成阻塞状态,然后调用其他的任务去运行。
|
|
|
.运行→就绪:一个任务正在CPU上运行,这时由于种种原因(如该任务的时间片用完,或另一个高优先级任务就绪),调度器选择了另一个任务去运行。这样对于当前的任务来说,就从运行状态变成了就绪状态。
|
|
|
.就绪→运行:处于就绪状态的任务被调度器选中去运行。
|
|
|
.阻塞→就绪:一个任务曾经因为等待某个事件而被阻塞起来,如果它等待的事件发生了,那么该任务就从阻塞状态变成了就绪状态,从而具备了继续运行的条件。
|
|
|
|
任务控制块(Task Control Block,TCB)是操作系统中的重要概念,任务管理就是通过对各个任务的TCB的操作来实现的。
|
|
|
所谓TCB,就是在操作系统当中,用来描述和管理一个任务的数据结构。系统为每一个任务都维护了一个相应的TCB,用来保存该任务的各种相关信息。TCB的内容主要包括任务的管理信息、CPU上下文信息和资源管理信息。
|
|
|
(1)任务的管理信息。包括任务的标识ID、任务的状态、任务的优先级、任务的调度信息、任务的时间统计信息、各种队列指针等。
|
|
|
(2)CPU上下文信息。指CPU中各寄存器的当前值,包括通用寄存器、PC寄存器、程序状态字、栈指针等。前面所述进程中的逻辑寄存器就是TCB当中的相应字段,是一些内存变量。另外,在实际的嵌入式系统中,CPU上下文信息不一定直接存放在TCB当中,而是存放在任务的栈中,可以通过相应的栈指针来访问。
|
|
|
(3)资源管理信息。如果在操作系统中,任务表示的是进程,则还应包含一些资源管理方面的信息,如段表地址、页表地址等存储管理方面的信息;根目录、文件描述字等文件管理方面的信息。
|
|
|
在嵌入式操作系统中,可以用TCB来描述任务的基本情况以及它的运行变化过程,把TCB看成是任务存在的唯一标志。具体来说,当需要创建一个新任务的时候,就为它生成一个TCB,并初始化这个TCB的内容。当需要中止一个任务的时候,只要回收它的TCB即可。而对于任务的组织和管理,也可以通过对它们的TCB的组织和管理来实现。
|
|
|
|
假设一个任务正在CPU上运行,这时由于某种原因,系统决定调度另一个任务去运行。那么在这种情形下,就要进行一次任务切换,把当前任务的运行上下文保存起来,并恢复新任务的上下文。
|
|
|
|
|
②更新当前任务的状态,从运行状态变为就绪状态或阻塞状态。
|
|
|
③按照一定的策略,从所有处于就绪状态的任务中选择一个去运行。
|
|
|
|
⑤根据新任务的TCB内容,恢复它的运行上下文环境。
|
|
|
|
如前所述,在一个多任务操作系统中,各个任务的状态是经常变化的,有时处于运行状态,有时处于就绪状态,有时又处于阻塞状态。即便同是阻塞状态,引发阻塞的原因可能又各不相同,有的是因为等待I/O操作,有的是因为任务之间的同步。因此,在一个操作系统当中,采用什么样的方式来组织它的所有任务,将直接影响到对这些任务的管理效率。
|
|
|
通常的做法是采用任务队列的方式,也就是说,由操作系统来维护一组队列,用来表示系统当中所有任务的当前状态,不同的状态用不同的队列来表示。例如,处于运行状态的所有任务构成了运行队列,处于就绪状态的所有任务构成了就绪队列,而对于处于阻塞状态的任务,则要根据它们阻塞的原因,分别构成相应的阻塞队列。然后,对于系统当中的每一个任务,根据它的状态把它的TCB加入到相应的队列当中去。如果一个任务的状态发生变化,例如,从运行状态变成就绪状态,或者从阻塞状态变成就绪状态,这时,就要把它的TCB从一个状态队列中脱离出来,加入到另一个队列当中去。
|
|
|