目录
一、信号量的特性
信号量(Semaphore)是一种实现任务间通信的机制,可以实现任务之间同步或临界资源的互斥访问,其实信号量主要的功能就是实现任务之间的同步与互斥,实现的方式主要就是依靠队列(信号量是特殊的队列)的任务阻塞机制。
1、信号量跟队列的对比
差异列表如下:
| 队列 | 信号量 |
|---|---|
| 可以容纳多个数据,创建队列时有两部分内存: 队列结构体、存储数据的空间 | 只有计数值,无法容纳其他数据。 创建信号量时,只需要分配信号量结构体 |
| 生产者:没有空间存入数据时可以阻塞 | 生产者:用于不阻塞,计数值已经达到最大时返回失败 |
| 消费者:没有数据时可以阻塞 | 消费者:没有资源时可以阻塞 |
由上面的表格可以看出:信号量相比队列更节省空间,因为实现同步与互斥不需要传递数据,所以信号量没有队列后面的环形存储区,信号量主要就是依靠计数值 uxMessagesWaiting(在队列中表示队列现有消息个数,在信号量中表示有效信号量个数)。
其实,创建信号量就对应创建特殊队列,获取信号量就对应队列出队,释放信号量就对应队列入队,学好了队列就基本学好了信号量。
2、两种信号量的对比
信号量的计数值都有限制:限定了最大值。如果最大值被限定为 1,那么它就是二值信号量;如果最大值不是 1,它就是计数型信号量。
| 二值信号量 | 计算型信号量 |
|---|---|
| 被创建时初始值为 0 | 被创建时初始值可以设定 |
| 其他操作是一样的 | 其他操作是一样的 |
二、信号量
首先来看一下信号的种类,相关的信号量函数放在第三章。
1、二值信号量
所谓二值信号量其实就是一个队列长度为1,没有数据存储器的队列,而二值则表示计数值uxMessagesWaiting只有0和1两种状态(就是队列空与队列满两种情况),uxMessagesWaiting在队列中表示队列中现有消息数量,而在信号量中则表示信号量的数量。
uxMessagesWaiting为 0 表示:信号量资源被获取了.uxMessagesWaiting为 1 表示:信号量资源被释放了
把这种只有 0 和 1 两种情况的信号量称之为二值信号量。
由于二值信号量就是特殊的队列,其实它的运转机制就是利用了队列的阻塞机,从而达到实现任务之间的同步与互斥(有优先级反转的缺陷)。
1.1 二值信号量用于同步
在多任务系统中,经常会使用二值信号量来实现任务之间或者任务与中断之间的同步,比如,某个任务需要等待一个标记,那么任务可以在轮询中查询这个标记有没有被置位,则任务在等待的过程也会消耗 CPU 的资源,如下所示:
// 任务一
void Task1Function(void *param)
{
volatile int i = 0;
while (1) {
for (i = 0; i < 10000000; ++i) {
sumj++;
}
flagCalcEnd = 1;
vTaskDelete(

最低0.47元/天 解锁文章
1781

被折叠的 条评论
为什么被折叠?



