在多线程程序中,线程之间通常存在分工。 在一种常见模式中,一些线程是生产者,一些是消费者。
需要强制执行几个同步约束才能使此系统正常工作:
在缓冲区中添加或删除项目时,缓冲区处于不一致状态。 因此,线程必须具有对缓冲区的独占访问权限。
如果消费者线程在缓冲区为空时到达,则会阻塞,直到生产者添加新项目为止。
初始化
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);
}
可以看到消费者会丢事件!