总体来说两者对于任务/线程的划分有这些区别,vx的状态更细化且没有运行态,还有就是对suspend的不同定义,个人理解如下
1. RTT把对资源的阻塞和时间的Delay都归纳为挂起态,就是RTT中的suspend。 RTT没有休眠态。
2. VX的悬置态可理解为对资源的等待而引起阻塞(PEND),延迟态是对等待时间DELAY而引起的阻塞.
而VX的SUSPEND是进入休眠的一种操作TaskSuspend。
VX没有挂起这个说法,可能是翻译带来的一种解释
VX的组合态是比较晦涩,不太好懂(延迟态+S、悬置态+S、悬置态+T、悬置态+S+T)
3. 看起来是RTT划分起来,简洁一些
vxWorks具有四种任务状态
就绪态(Ready):任务只等待系统分配CPU资源
悬置态(Pend):任务需等待某些不可利用的资源而被阻塞。 可理解成RTT的PEND, 阻塞
休眠态(Sleep):如果系统不需要某一个任务工作,则这个任务处于休眠状态。
延迟态(Delay):任务被延迟时所处的状态。
当系统对某一任务进行操作时,任务就从一种状态跃迁到另一状态。处于任一状态的任务都可以被删除。
就绪态是指,任务已经获得除了CPU之外的所有其他资源,所等待的只是CPU的运行,一旦其他任务释放了CPU资源,该任务就可以开始运行。
休眠态表示任务正在等待除CPU之外的其他资源,即使当前CPU资源可以使用该任务也无法运行,通常也叫作阻塞状态。
处于延迟态的任务表示在其执行期间主动放弃了CPU资源并处于一种等待延迟时间的状态,这种任务不需要获取任何资源,所需要等待的仅仅是一段时间。
悬置态:任务需等待某些不可利用的资源而被阻塞。 有时是一种用于调试的状态,处于这种状态的任务不会因为其不运行而导致状态的转换
整个系统中处于运行态的任务只能有一个(单核心系统),这样的任务不缺少任何资源,也不需要等待时间延迟,通常其是由最高优先级的就绪态任务转换而来的。如果所有用户任务都不能处于就绪状态,系统将会运行一个IDLE任务。
除了这些基本状态之外,根据不同的组合还可以列出下面的状态:延迟态+S、悬置态+S、悬置态+T、悬置态+S+T以及带有继承优先级处于任何状态的任务(也就是延迟态、休眠态、悬置态三者之间的组合)。
VX中一些任务创建时的参数,还是需要理解一下的。
任务跃迁图下图所示:
下表列出了VxWorks中任务可能出现的状态,每个状态的后面都有一个简要地说明。图1.1给出的任务基本状态转换图中描绘了任务基本状态的转换以及状态之间的关系。
状 态 | 描 述 |
就绪态 | 任务正在等待CPU资源 |
休眠态 | 任务正在等待除CPU资源之外的其他资源 |
延迟态 | 任务正在等待一定时间的延时 |
悬置态 | 任务无法执行,主要是用于调试的一种状态。这种状态仅影响任务的执行而不影响任务状态的转换。处于阻塞挂起状态的任务仍然可以被解锁,处于睡眠挂起的任务仍然可以被唤醒 |
延迟态+ S | 处于睡眠挂起的任务状态 |
悬置态+ S | 处于阻塞挂起的任务状态 |
悬置态+ T | 带有超时值的处于阻塞的任务状态 |
悬置态+ S + T | 带有超时值的处于阻塞且挂起的任务状态 |
state + I |
带有继承优先级处于state状态的任务 |
任务状态的转换主要原因有两个:等待资源和放弃CPU资源。放弃CPU资源将使任务处于延迟态,等待CPU资源将使任务处于就绪态,等待其他资源的任务则处于休眠态。这里所指的其他资源包括信号量、外部设备、消息队列等,凡是程序运行所需要用到的都可以归结到这个范围。
表1.2列出了任务状态转换以及可能引发这些转换的函数。这些函数中大多是系统提供的操作API,任务状态的转换可以通过这些函数完成但并不局限于这些方法。
状 态 转 换 | 函 数 |
就绪态→悬置态 | semTake( )/msgQReceive( ) |
就绪态→延迟态 | taskDelay( ) |
就绪态→休眠态 | taskSuspend( ) |
悬置态→就绪态 | semGive( )/msgQSend( ) |
悬置态→休眠态 | taskSuspend( ) |
延迟态→就绪态 | expired delay |
延迟态→休眠态 | taskSuspend( ) |
休眠态→就绪态 | taskResume( )/taskActivate( ) |
休眠态→悬置态 | taskResume( ) |
休眠态→延迟态 | taskResume( ) |
1.1启动线程
线程初始化时,默认被设置为初始状态。线程启动后(调用rt_thread_startup),先将线程设置为挂起态,然后恢复到就绪态(调用rt_thread_resume),紧接着执行线程调度。
1.2发生阻塞(线程挂起)
1.2.1延时。若正在运行态的线程无需任何通信或同步,它就有必要通过延时来让出CPU的控制权,否则比它低的线程将无法获得运行的机会。延时,就是让线程在可以接受的时间段休息一会儿(主动让出CPU控制权),具体的延时时间要根据实际情况来设计,在此不详述。
1.2.2等待线程通信或同步信号(信号量、互斥量、事件标志、接收邮箱、接收消息队列、内存池的分配)。往往,线程需要获取某些信号用来同步线程或者响应用户操作、执行某种请求等,为此,如果要获取的信号已经到来则立即执行接下来的程序,反之,就要先让出CPU的控制权,启动任务切换。
1.2.3由于特别需要,对某就绪态的线程挂起。比如,线程A在运行时,需要获取线程C的信号量,而此时,就绪表有更高优先级的线程B,但是线程B又要获取线程A接下来要发送的消息邮箱信息,这样正常的执行顺序是A->B->C->A->B.显然,我们可优化一下,在执行线程A未获取信号量时将线程B挂起,线程C取得了CPU控制权得到执行后线程A接着执行,在线程得到信号量后将线程B恢复,这样线程B得到CPU的控制权,即下图1.2.3.2的执行顺序A->C->A->B.