VxWorks中信号量实现任务间通信与同步机制分析

多任务内核、任务调度机制、任务间通信和中断处理机制,这些都是VxWorks运行环境的核心。多任务处理和任务间通信是实时操作系统的基石。一个多任务环境允许将一个实时应用构造成一套独立任务的集合,每一个都有自己独立的执行路线和自己的系统资源,完成不同的功能。任务间通信的机制则允许任务间的同步和通信,以调整系统的行为。VxWorks中,任务间通信的机制包括从快速信号量到消息队列、管道、网络传输套接口。

在一个实时系统中,可能有许多任务作为一个应用的一部分执行。系统必须为这些任务提供快速且功能强大的通信机制。内核也要提供能有效地共享不可抢占的资源或临界区所需的同步机制。

本文描述了VxWorks任务间通信与同步机制的几种方法,重点讨论了信号量在任务间的同步与互斥中的应用。

任务间通信

为了提供完整的多任务系统的功能,VxWorks内核提供了一套丰富的任务间通信与同步的机制。这些通信功能使一个应用中各个独立的任务协调它们的活动。任务间通信与同步的机制包括:共享内存,数据简单的共享;信号量,基本的互斥和同步;消息队列和管道,同一CPU内多任务间消息传递;Sockets和远程调用,任务间透明的网络通信;Sinals,用于异常处理。

共享数据结构
任务间通信最直接有效的方法是访问共享数据结构。由于所有VxWorks任务共存于单一的线性地址空间,多任务间共享数据结构是非常方便的,如图1所示。
  
不幸的是,共享地址空间具有上述优点的同时,带来了未被保护内存的重入访问的危险。


互斥
  当用一个共享地址空间作为数据交换时,通过互斥访问避免资源竞争就变为必要。用来获得一个资源的互斥访问的许多机制仅在这些互斥所作用的范围上存在差别。实现互斥的方法包括禁止中断、禁止任务抢占和通过信号量进行资源锁定。
  
(1)中断禁止
最强的互斥方法是屏蔽中断。这样的锁定保证了对CPU的互斥访问。这种方法当然能够解决互斥的问题,但它对于实时是不恰当的,因为它在锁定期间阻止系统响应外部事件。长的中断延时对于要求有确定响应时间的应用来说是不可接受的。因此不适合作为一种通用的互斥方法,但在涉及到ISR 需要互斥时,中断禁止又是必要的。但在任何情况下,应该使中断上锁时间尽量短。

(2)抢占禁止
禁止抢占提供了强制性较弱的互斥方式。当前任务运行的过程中不允许其他任务抢占,而中断服务程序可以执行。这也可能引起较差的实时响应,就象被禁止中断一样,被阻塞的任务会有相当长时间的抢占延时,就绪态的高优先级的任务可能会在能够执行前被强制等待一段不可接受的时间。为避免这种情况,在可能的情况下尽量使用信号量实现互斥。

信号量

VxWorks信号量是提供任务间通信、同步和互斥的最优选择,提供任务间最快速的通信。也是提供任务间同步和互斥的主要手段。VxWorks提供3种信号量来解决不同的问题。

二进制最快的最常用的信号量,可用于同步或互斥。

互斥为了解决内在的互斥问题、优先级继承、删除安全和递归等情况而最优化的特殊的二进制信号量。

计数器类似于二进制信号量,但是随信号量释放的次数改变而改变。

二进制信号量
二进制信号量能够满足任务间的互斥和同步,需要的系统开销最小。二进制信号量可以看成一个标志,对应资源是可用还是不可用。当一个任务调用semTake ()请求一个信号量时,如果此时信号量可用,信号量会被清零,并且任务立即继续执行;如果信号量不可用,任务会被阻塞来等待信号量。

  
当一个任务调用semGive ()释放一个二进制信号量时。如果信号量已经可用,释放信号量不会产生任何影响;如果信号量不可用并且没有任务等待使用该信号量,信号量只是被简单地置为可用;如果信号量不可用并且有一个或多个任务等待该信号量,最高优先级的任务被解阻塞,信号量仍为不可用。



互斥
当两个以上的任务共享使用同一块内存缓冲区或同一个I/O设备之类的资源时,可能会发生竞争状态。

二进制信号量可以通过对共享资源上锁,实现高效的互斥访问,不象禁止中断或禁止抢占,二进制信号量将互斥仅仅限于对与之联系的资源的访问,并且比禁止中断和禁止抢占提供更精确的互斥粒度。使用时创建用于保护资源的二进制信号量,初始时信号量可用。

当任务需要访问这个资源时,首先取得这个信号量,所有其它想要访问这个资源的任务将被阻塞。当任务完成了对该资源的访问时,释放该信号量,允许其他任务使用该资源。因此所有对一个需要互斥访问资源的操作由semTake ()和semGive ()对一起来实现。

semTake(semMutex,WAIT FOREVER)
临界区,某一时刻仅被一个任务访问
semGive (semMutex)

同步
信号量另一种通常的用法是用于任务间的同步机制。在这种情况下,信号量代表一个任务所等待的条件或事件。最初,信号量是不可用的。一个任务或中断处理程序释放该信号量来通知这个事件的发生。等待该信号量的任务将被阻塞直到事件发生、该信号量可用。一旦被解阻塞,任务就执行恰当的事件处理程序。信号量在任务同步中的应用对于将中断服务程序从冗长的事件处理中解放出来以缩短中断响应时间是很有用的。

互斥信号量
互斥信号量是一种特殊的二进制信号量,用于解决具有内在的互斥问题:优先级继承、删除安全和对资源的递归访问等情况。

互斥信号量与二进制不同点在于:①它仅用于互斥;②仅能由取(semTake ())它的任务释放;③不能在ISR 中释放(semGive ())。

(1)优先级继承
优先级倒置发生在一个高优先级的任务被迫等待一段不确定时间,等待一个低优先级任务完成。VxWorks允许使用优先级继承算法,在互斥信号量中使用选项SEM-INVERSION-SAFE ,将使能优先级继承算法,优先级继承协议确保拥有资源的任务以阻塞在该资源上的所有任务中优先级最高的任务的优先级执行,直到它释放所拥有的所有信号量,然后该任务返回到正常状态。因此这个“继承的高优先级”任务受到不会被任何中间优先级任务抢占的保护。

(2)删除安全
另一个互斥问题涉及到任务删除。在一个受信号量保护的临界区,经常需要保护在临界区执行的任务不会被意外地删除。删除一个在临界区执行的任务可能引起意想不到的后果,造成保护资源的信号量不可用,可能导致资源处于破坏状态,也就导致了其他要访问该资源的所有任务无法得到满足。

原语taskSafe()和taskUnsafe ()提供了防止任务被意外删除的一种方法。同时互斥信号量提供了选项SEM-DELETE-SAFE ,使用这个选项,每次调用semTake ( )时隐含地使能了taskSafe(),当每次调用semGive ()时隐含地使能了taskUnsafe ()这种方式,任务得到信号量时得到不会被删除的保护。

(3)递归资源访问
互斥信号量能够被递归地获得。这意味着信号量能够被一个拥有该信号量的任务在该信号量最终被释放之前多次获取。递归对于满足一些子程序即要求能够相互调用但是也要求互斥访问一个资源非常有用。这种情形是可能的,因为系统需要跟踪哪一个任务当前拥有信号量。

计数器信号量
计数器信号量是实现任务同步和互斥的另一种手段。计数器信号量除了像二进制信号量那样工作外,还保持对信号量释放次数的跟踪。信号量每次释放,计数器加一,每次获取,计数器减一。当信号量减到0 时,试图获取该信号量的任务被阻塞。

正如二进制信号量,当信号量释放时,如果有任务阻塞在该信号量阻塞队列上,那么任务解除阻塞;但是如果信号量释放时,没有任务阻塞在该信号量阻塞队列上,那么计数器加一。

结 论

通过对嵌入式操作系统VxWorks的多任务之间的通信机制的分析可以看出,信号量在实现多任务间的通信、同步和互斥中发挥着重要的作用。因此,深入理解和正确使用VxWorks的信号量,可以提高实时系统中多任务间通信的效率。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值