《VxWorks中信号量实现任务间通信同步与互斥,代码.doc》由会员分享,可在线阅读,更多相关《VxWorks中信号量实现任务间通信同步与互斥,代码.doc(4页珍藏版)》请在金锄头文库上搜索。
1、VxWorks信号量是提供任务间通信、同步和互斥的最优选择,提供任务间最快速的通信。也是提供任务间同步和互斥的主要手段。VxWorks提供3种信号量来解决不同的问题。二进制信号量是最快的最常用的信号量,可用于同步或互斥。互斥为了解决内在的互斥问题、优先级继承、删除安全和递归等情况而最优化的特殊的二进制信号量。计数器类似于二进制信号量,但是随信号量释放的次数改变而改变。二进制信号量semBCreate (SEM_Q_FIFO/SEM_Q_PRIORITY , SEM_EMPTY/SEM_FULL)有两个作用:(1)任务间的互斥 同一个任务获取和释放信号量,防止两个任务同时存取一个资源(2)任务间
2、的同步 一个任务获取信号量,另一个任务(或者中断)释放信号量二进制信号量实现互斥使用二进制信号量可以很方便的实现互斥,互斥是指多任务在访问临界资源时具有排他性。为了使多个任务互斥访问临界资源,只需要为该资源设置一个信号量,相当于一个令牌,那个任务拿到令牌即有权使用该资源。把信号量设置为可用,然后把需要的资源 的任务的临界代码 置于semTake()和semGive()之间即可。 注明:1、互斥中的信号量与任务优先级的关系:任务的调度还是按照任务优先级进行,但是在使用临界资源的时候只有一个任务获得信号量,也就是说还是按照任务优先级获得信号量从而访问资源。只是当前使用资源的任务释放信号量semGi
3、ve(),其它任务按照优先级获得信号量。 2、信号量属性中的参数为:SEM_Q_PRIORITY。而且在创建信号量的时候必须把信号量置为满SEM_FULL。即信号量可用。 基本实现互斥模型: SEM_ID semMutex; semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL); task(void) semTake(semMutex, WAIT_FOREVER);/得到信号量,即相当于得到使用资源的令牌 /临界区,某一个时刻只能由一个任务 访问 semGive(semMutex); 二进制信号量实现同步同步即任务按照一定的顺序先后执行,为了实现任务A
4、和B同步,只需要让任务A和B共享一个信号量,并设置初始值为空,即不可用,将semGive()置于任务A之后,而在任务B之前插入semTake()即可。 说明:1、还是讨论和优先级的关系。由于信号量初始化为空,不可用,所以可能使得优先级反转,即高优先级任务B在等待低优先级任务A释放信号量。只有执行了信号量释放语句semGive()后任务B得到信号量才能执行。 2、属性参数的设置为SEM_Q_FIFO,SEM_EMPTY; 实现模型参考 SEM_ID semSync; semSync = semBCreate(SEM_Q_FIFO, SEM_EMPTY); taskA(void) . semGiv
5、e(semSync); /信号量释放,有效 taskB(void) semTake(semSync, WAIT_FOREVER); /等待信号量 . 使用信号量注意事项: 1、用途不同,信号量属性和初始值不同 2、互斥访问资源时,semTake()和semGive()必须成对出现,且先后顺序不能颠倒。 3、避免删除那些其它任务正在请求的信号量。 互斥信号量semMCreate(SEM_Q_PRIORITY/SEM_Q_FIFO/SEM_DELETE_SAFE/SEM_INVERSION_SAFE)是二进制信号量的一种特殊形式,在不需要用到删除安全/优先级反转/递归调用属性时,与二进制信号量的互
6、斥功能相同。特点:(1)只能用于任务间的互斥(2)只能由take它的任务give(3)不能在中断中take或give(4)可以递归调用,也就是同一个任务可以反复多次获取信号量,这个特性在某些时候非常有用,如funcA需要获取某个互斥信号量,funcA会调用funB,而funcB因为还有可能被其他函数调用也需要获取这个信号量,这时候就可以用互斥信号量来实现。SEM_ID semM;semM = semMCreate (.);funcA () semTake (semM, WAIT_FOREVER); . funcB (); . semGive (semM);funcB () semTake (s
7、emM, WAIT_FOREVER); . semGive (semM);但是释放和获取信号量必须成对,也就同一个任务获取几次,也必须释放几次,不然会造成别的任务无法获取到,虽然这个任务本身还是可以获取到。编程时使用的几个信号量的参数SEM_Q_PRIORITY (0x1) 阻塞在这个信号量上的任务凭任务优先级高低来决定谁先获取到信号量SEM_Q_FIFO (0x0) 阻塞在这个信号量上的任务按先入先出顺序获取到信号量SEM_DELETE_SAFE (0x4) 获取到这个信号量的任务在信号量未释放之前,删除这个任务时会被阻塞直到信号量释放为止。SEM_INVERSION_SAFE (0x8) 获取到这个信号量的任务将以阻塞在这个信号量的所有任务中的最高优先级来运行,防止优先级反转情况发生(优先级反转是指中间优先级任务抢占获取到互斥信号量的低优先级任务,导致阻塞在同一个信号量上的高优先级任务要等中间优先级任务运行完成之后才能运行。必须与SEM_Q_PRIORITY一起使用。信号量的一些调试命令semShow(semId, 0/1),查看信号量属性及阻塞在这个信号量上的任务ShowSemPend, 查看系统中所有阻塞在某个信号量上的任务信息及这个信号量的当前占用者(OSS命令)semMGiveForce(semId), 强制释放互斥信号量