Wind内核中有二进制信号量、计数信号量和互斥信号量三种类型,为了使应用程序具有可移植性,还提供了POSIX(可移植操作系统接口)信号量。在Vxorks操作系统中,信号量是实现任务同步的主要手段,也是解决任务同步问题的最佳选择。
使用二进制信号量可以很方便的实现互斥,互斥是指多任务在访问临界资源时具有排他性。为使多个任务互斥访问临界资源,只需要为该资源设置一个信号量,相当于一个令牌,哪个任务拿到这个令牌即有权使用该资源。把信号量设为可用,然后将需要资源的任务的临界代码置于semTake()和SemGive()之间即可。
注明:
基本实现互斥模型:
SEM_IDsemMutex;
semMutex = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
task(void)
{
semTake(semMutex,WAIT_FOREVER);//得到信号量,即相当于得到使用资源的令牌
//临界区,某一个时刻只能由一个任务访问;
semGive(semMutex);
}
同步即任务按照一定顺序先后执行,为了实现任务A和B的同步,只需要让任务A和B共享一个信号量,并设初始值为空,即不可用,将semGive()置于任务A之后,而在任务B之前插入semTake()即可.
说明:
实现模式参考:
SEM_ID semSync;
semSync = semBCreate(SEM_Q_FIFO,SEM_EMPTY);
taskA(void)
{
……….
semGive(semSync);//信号量释放,有效。
}
taskB(void)
{
semTake(semSync,WAIT_FOREVER);//等待信号量。
……..
}
:
1、确保任务优先级不反转:
SEM_IDsemFs;
SEM_IDsemFss;
SEM_IDsemFex;
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);
}
以上例子虽然定了各个任务的优先级,但加上信号量可以实现同步,而且防止优先级反转出现。
2、也可以实现反转。有兴趣的可以将以上优先级改一下试试看。