6-2 有限缓冲区的生产者

参考https://blog.csdn.net/booksyhay/article/details/82743623
在6-1中的生产者方案中:
在这里插入图片描述
尽管这种解决方案是正确的,但仍有机会对其性能进行一次小改进。 想象一下,当生产者发出信号时,至少有一个消费者在队列中。 如果调度程序允许消费者运行,接下来会发生什么? 它会立即阻塞生产者(仍然)持有的互斥锁。

阻塞和唤醒是中等昂贵的操作; 不必要地执行它们会损害程序的性能。 所以重新排列生产者可能会更好:
在这里插入图片描述
改进后的生产者代码:

int put_events = 0;
while(1)
{
	wait_event();
	osSemaphoreAcquire(sem_mutex, osWaitForever);
	{
		event_add(&put_events);
		printf("put events: %d\r\n", put_events);	
	}
	osSemaphoreRelease(sem_mutex);
	osSemaphoreRelease(sem_items);
    osDelay(1500);
}

上面的生产者与消费者,共享缓冲区是无限的,实际情况并非如此,改进上面的方案:
添加第二个信号量以跟踪缓冲区中的可用空间数
具有有限缓冲区的生产者 - 消费者
在这里插入图片描述
当消费者移除项目时,它应该发送信号给spaces。 当生产者到达时,它应该递减spaces信号量,此时它可能会阻塞,直到下一个消费者发出信号。
为了避免死锁,生产者和消费者在获取互斥锁之前检查可用性。 为获得最佳性能,他们会在发出信号之前释放互斥锁。

初始化
其中sem_spaces 初始化为5

osSemaphoreId_t sem_mutex;
sem_mutex = osSemaphoreNew(1, 1, NULL);

osSemaphoreId_t sem_mutex;
sem_items = osSemaphoreNew(1, 0, NULL);

osSemaphoreId_t sem_spaces;
sem_spaces = osSemaphoreNew(5, 5, NULL);

生产者

int put_events = 0;
while(1)
{
	wait_event();
	printf("available sems: %d\r\n", osSemaphoreGetCount(sem_spaces));
	osSemaphoreAcquire(sem_spaces, osWaitForever);
	
	osSemaphoreAcquire(sem_mutex, osWaitForever);
	{
		event_add(&put_events);
		printf("put events: %d\r\n", put_events);	
	}
	osSemaphoreRelease(sem_mutex);
	osSemaphoreRelease(sem_items);
    osDelay(500);
}

消费者

int get_events = 0;
while(1)
{
	osSemaphoreAcquire(sem_items, osWaitForever);
	osSemaphoreAcquire(sem_mutex, osWaitForever);
	{
		event_get(&get_events);
	}
	osSemaphoreRelease(sem_mutex);
	osSemaphoreRelease(sem_spaces);
	
	event_process(get_events);
	osDelay(2000);
}

其中特意将消费的速率明显大于生产的速率!

结论:
在这里插入图片描述
可以看到sem_spaces信号量有效数减为0后,生产者置事件需要消费者释放sem_spaces,才能放入事件。而且可以看到消费者获取的事件值是生产者生产的上一个事件值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值