VxWorks信号量SEM_FULL/SEM_EMPTY分析

转载 2011年01月12日 19:19:00
Wind内核中有二进制信号量、计数信号量和互斥信号量三种类型,为了是运用程序具有可移植性,还提供了POSIX(可移植操作系统接口)信号量 。在VxWorks中,信号量是实现任务同步的主要手段,也是解决任务同步的最佳选择。
  • 关于互斥的实现:
使用二进制信号量可以很方便的实现互斥,互斥是指多任务在访问临界资源时具有排他性。为了使多个任务互斥访问临界资源,只需要为该资源设置一个信号量,相当于一个令牌,那个任务拿到令牌即有权使用该资源。把信号量设置为可用,然后把需要的资源 的任务的临界代码 置于semTake()和semGive()之间即可。
注明:1、互斥中的信号量与任务优先级的关系:任务的调度还是按照任务优先级进行,但是在使用临界资源的时候只有一个任务获得信号量,也就是说还是按照任务优先级获得信号量从而访问资源。只是当前使用资源的任务释放信号量semGive(),其它任务按照优先级获得信号量。
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和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)
  {
     ......
     semGive(semSync);      //信号量释放,有效
  }
  taskB(void)
  {
     semTake(semSync, WAIT_FOREVER);   //等待信号量
      ....
  }
使用信号量注意事项:
1、用途不同,信号量属性和初始值不同
2、互斥访问资源时,semTake()和semGive()必须成对出现,且先后顺序不能颠倒。
3、避免删除那些其它任务正在请求的信号量。
应用:
1、确保任务优先级不反转
    SEM_ID semFs;
    SEM_ID semFss;
    SEM_ID semFex;
    semFs = semBCreate(SEM_Q_FIFO,  SEM_EMPTY);
    semFss = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
    semFex = semBCreate(SEM_Q_FIFO, SEM_EMPTY);
    void t_imaGet(void)
   {
       printf("a   ");
       semGive(semFs);   //释放信号量
   }
   void t_imaJud(void)
   {
        semTake(semFs, WAIT_FOREVER);    //确保优先级不反转
        printf("jj ");
        semGive(semFss);
   }
   void t_imaPro(void)
   {
        semTake(semFss, WAIT_FOREVER);
        printf("rr");
        semGive(semFex);
   }
   void t_imaExc(void)
   {
        semTake(semFex, WAIT_FOREVER);
        printf("Y");
   }
    void start(void)
   {
           int tGetId, tJudId, tProId, tExcId;
           tGetId = taskSpawn("tPget", 200, 0, 1000,(FUNCPTR)t_imaGet, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0);
           tJudId = taskSpawn("tPjud",201,0,1000,(FUNCPTR)t_imaJud,3,0,0,0,0,0,0,0,0,0); 

            tProId = taskSpawn("tPpro",202,0,1000,(FUNCPTR)t_imaPro,3,0,0,0,0,0,0,0,0,0);

             tExcId = taskSpawn("tPexc",203,0,1000,(FUNCPTR)t_imaExc,3,0,0,0,0,0,0,0,0,0);
}
以上例子虽然定了各个任务的优先级,但是加上信号量可以 实现同步,而且防止优先级反转的出现。
vxworks一个任务和信号量的测试程序
这个程序有利于自己对信号量的理解
#include "semLib.h" 
#include "taskLib.h"
#include "osdrv.H"
/*测试适配的任务和信号量的函数*/
void taskSub1();
void taskSub2();
XHANDLE semm;
void taskMain() /*主任务:在shell下输入sp taskMain*/
{
    XHANDLE subId1,subId2;
    semm="SimOs"_CreateSemaphore(1, "no name");/*生成信号量*/
    printf("semm OK/n");
    subId1=SimOs_CreatThread(taskSub1, 0, 0, XTASK_PRIORITY_ABOVE_NORMAL,XW_DEFAULT, 2000, 0, "taskSub");/*生成子任务,优先级比主任务的100要高*/
    printf("taskSub1 spawned/n");
    subId2=SimOs_CreatThread(taskSub2, 0, 0, XTASK_PRIORITY_ABOVE_NORMAL,XW_DEFAULT, 2000, 0, "taskSub");/*生成子任务,优先级比主任务的100要高*/
    printf("taskSub2 spawned/n");
    taskSuspend(0);
    if(taskDelete(subId1)!=OK)
      printf("delete taskSub error:%d/n",errno);
    else
      printf("taskSub deleteed.OK/n"); 
    if(taskDelete(subId2)!=OK)
      printf("delete taskSub error:%d/n",errno);
    else
      printf("taskSub deleteed.OK/n");       
      
}
void taskSub1()
{
     SimOs_ObtainSemaphore(semm, XW_INFINITE);/*获取信号量*/
     taskSuspend(0);
     printf("taskSub:resumed and release mutex1a/n");
     SimOs_ReleaseSemaphore(semm);/*释放信号量*/
     printf("taskSub:resumed and release mutex1b/n");
 
}
void taskSub2()
{    printf("come into the taskSub2/n");
     SimOs_ObtainSemaphore(semm, XW_INFINITE);/*获取信号量*/
     printf("taskSub:resumed and release mutex2a/n");
     SimOs_ReleaseSemaphore(semm);/*释放信号量*/
     printf("taskSub:resumed and release mutex2b/n");
 
}

相关文章推荐

关于信号量sem_wait的整理(转)

SYNOPSIS        #include        int sem_init(sem_t *sem, int pshared, unsigned int va...

信号量 sem_timedwait 函数的使用

信号量 sem_timedwait 函数的使用

信号量sem_t,互斥锁pthread_mutex_t的使用

信号量的数据类型为结构sem_t,它本质上是一个长整型的数。 ------函数sem_init()用来初始化一个信号量。        它的原型为: extern int sem_init __P...

信号量sem_t,互斥锁pthread_mutex_t的使用

信号量的数据类型为结构sem_t,它本质上是一个长整型的数。 ------函数sem_init()用来初始化一个信号量。        它的原型为: exter...
  • hpwzd
  • hpwzd
  • 2012-03-18 09:48
  • 1844

信号量sem_wait()的使用

闲来无事,我给大家讲下UNIX/Linux下信号量函数的使用。 首先你得知道什么叫信号量,什么时候要用信号量。 这个嘛,主要就是用来保护共享资源的,也就是说如果你想限制某个(些)资源在同一...

信号量sem_wait()的使用

闲来无事,我给大家讲下UNIX/Linux下信号量函数的使用。 首先你得知道什么叫信号量,什么时候要用信号量。 这个嘛,主要就是用来保护共享资源的,也就是说如果你想限制某个(些)资源在同一...

Linux 信号量sem_wait(3) (翻译 man 3)

SEM_WAIT(3) Linux Programmer's Manual SEM_WAIT(3) NAME sem_wait, sem_timedwait, sem_trywait - loc...

C++多线程框架 (二)---------Mutex互斥和Sem信号量

互斥和信号量是多线程编程的两个基础,其原理就不详细说了,大家去看看操作系统的书或者网上查查吧。 对于互斥的实现,无论什么操作系统都离不开三个步骤 1.初始化互斥锁 2.锁操作 ...

线程互斥锁、信号量sem_t、bufsem.c

摘自:百度百科

关于信号量sem_wait的整理(转)

SYNOPSIS        #include        int sem_init(sem_t *sem, int pshared, unsigned int va...
  • tietao
  • tietao
  • 2011-09-27 11:16
  • 2361
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)