6-1 生产者-消费者问题

在多线程程序中,线程之间通常存在分工。 在一种常见模式中,一些线程是生产者,一些是消费者。

需要强制执行几个同步约束才能使此系统正常工作:

在缓冲区中添加或删除项目时,缓冲区处于不一致状态。 因此,线程必须具有对缓冲区的独占访问权限。
如果消费者线程在缓冲区为空时到达,则会阻塞,直到生产者添加新项目为止。

初始化
在这里插入图片描述
mutex提供对缓冲区的独占访问。 当items为正数时,它表示缓冲区中项目的数量。 如果为负数,则表示队列中排队的消费者线程数。

信号量初始化

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

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

事件缓存初始化

int event_buffer[256] = {0};
int now_events = 0;

事件添加

void event_add(int* event)
{
	*event = *event + 1;/*模拟事件值*/
	event_buffer[now_events] = *event;
	now_events++;
}

事件获取

void event_get(int* event)
{
	*event = event_buffer[now_events - 1];
	now_events--;
}

模拟事件等待

void wait_event()
{
	osDelay(100);
}

模拟事件处理

void event_process(int event)
{
	printf("get events: %d\r\n", event);
}

生产者线程
在这里插入图片描述

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_items);
	}
	osSemaphoreRelease(sem_mutex);
    osDelay(1500);
}

消费者线程
在这里插入图片描述

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

结论:
在这里插入图片描述
可以看到put与get是成对出现的,生产一个事件,消费一个事件;这个前提是在生产者的速度比消费者的速度慢的情况下。

提高生产者的速度:
生产者线程修改为:

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_items);
	}
	osSemaphoreRelease(sem_mutex);
    osDelay(500);
}

在这里插入图片描述
可以看到消费者会丢事件!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值