信号量是VxWorks提供的最常用,最快速的一种任务间通信机制。VxWorks中信号量有三种:二值信号量,互斥信号量,计数信号量。下面一一介绍这三种信号量的作用与区别。
信号量通常的作用就是是控制任务的同步与互斥,
控制同步:任务1中等待信号量X,当任务2中提供信号量后触发任务1继续运行
void fooInTask1() { semTake(...); // wait for sem X // if sem is given, continue the execution ... } void fooInTask2() { semGive(...); // give sem X and trigger task1 }
控制互斥:先通过先锁定某信号量,在临界区代码结束后释放该信号量。当然这里必须保证开始时该信号量是可用的。
void fooB() { semTake(...); // lock sem X // critical region of code ... semGive(...); // unlock sem X }
而在达成这些目标时这三种信号量又有如下区别。
二值信号量,是这三种中最通用,最快速的方式。通过semBCreate创建,可以同时支持同步和互斥的控制。当用作同步时,一般创建时设置为不可用(SEM_EMPTY),而当用作互斥时,则再创建时一般设置为可用(SEM_FULL)。
互斥信号量,属于一种特殊的二值信号量,一般都被用于控制互斥访问,同时支持优先级继承,任务删除安全等选项。互斥信号量与二值相比有如下不同:
1. 通过semMCreate创建时,初值为可用
2. 对互斥信号量,semTake和semGive总是成对出现
3. 不可使用semFlush来释放信号
4. 在创建时可以选择是否支持优先级继承,任务删除安全等特性。(优先级继承是为了防止优先级反转,任务删除安全是通过taskSafe和taskUnsafe来保证运行在临界区内时不会被意外删除)
计数信号量,也就是支持计数的二值信号量,它会对信号量的释放次数进行跟踪,每次释放计数器加1,每次获取则减1,当计数值为0时试图获取信号量的任务被阻塞。它由semCCreate来创建。
最后在说明下再创建信号量时,都可以指定类型为SEM_Q_PRIORITY 或 SEM_Q_FIFO,当多个任务同时等待SEM_Q_PRIORITY类型的信号量时,当信号量来临,优先级更高的任务会获得信号量被触发,而SEM_Q_FIFO类型的话,则是最先开始等待的任务获得。