1. 程式人生 > >【Linux】基於環形buf的多消費者多生產者問題

【Linux】基於環形buf的多消費者多生產者問題

生產者消費者問題,是一個多執行緒同步問題的經典案例。該問題描述了兩個共享固定大小緩衝區執行緒——即所謂的“生產者”和“消費者”——在實際執行時會發生的問題。生產者的主要作用是生成一定量的資料放到緩衝區中,然後重複此過程。與此同時,消費者也在緩衝區消耗這些資料。該問題的關鍵就是要保證生產者不會在緩衝區滿時加入資料,消費者也不會在緩衝區中空時消耗資料。

下面是該問題的環形模型


當生產者在生產時,消費者不能進行消費,當消費者在消費時生產者不能進行生產,這些都說的是在同一資料操作區進行操作

以上圖為例,即消費者永遠不能追上生產者,生產者永遠不能追上消費者,更別說超過一圈了

下面是用程式碼實現

#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<pthread.h>
#include<semaphore.h>
#define _SIZE_ 64
sem_t blanks;
sem_t datas;
int buf[_SIZE_]={
	0
};
//pthread_lock_t mylock;
void *product(void * arg)
{
  int i=1;
  while(1){
  
      for(i=0;i<=_SIZE_;i++)
	  {
	  sleep(1);
	  if(buf[i]==0)
	  {
	  sem_wait(&blanks);
	  int _product=rand()%123;
      buf[i]=i;
	  printf("product is:%d,data is :%d\n",_product,i);
	  sem_post(&datas);
	  }
	  }
  }
}
void *consumer()
{
  int i=1;
  while(1){
      sem_wait(&datas);
	  for(;i<=_SIZE_;i++)
	  {
	  sleep(1);
	  if(buf[i]!=0)
	  {
	  int _consumer=rand()%1242;
	  printf("consumer :%d,data is:%d\n",_consumer,i);
	  buf[i]=0;

	  }
	  }
      sem_post(&blanks);
  }
}
void run()
{
    sem_init(&blanks,0,_SIZE_);
	sem_init(&datas,0,0);
	pthread_t _consumer;
	pthread_t _product;
	pthread_create(&_consumer,NULL,consumer,NULL);
	pthread_create(&_product,NULL,product,NULL);
	pthread_join(_consumer,NULL);
	pthread_join(_product,NULL);
    sem_destroy(&blanks);
	sem_destroy(&datas);
}
int main()
{
	run();
	return 0;
}

執行結果

可以看出有多個消費者在消費,多個生產者在生產,並且消費者總是在生產者後面消費