生产者消费者模型——基于Posix信号量和互斥量

这种方式可以用信号量初值来定义仓库大小,循环生产和消费

生产者:

while(1)
{
    pthread_mutex_lock(&mutex);
    sem_wait(&sem_full);
    生产
    sem_post(&sem_empty);
    pthread_mutex_unlock(&mutex);
}

消费者:

while(1)
{
    pthread_mutex_lock(&mutex);
    sem_wait(&sem_empty);
    消费
    sem_post(&sem_full);
    pthread_mutex_unlock(&mutex);
}

代码实现:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>

#define PRO_COUNT 3
#define COM_COUNT 3
#define BUFSIZE 5

int buf[BUFSIZE];//仓库
int num=1;//产品编号
int rd_idx=1;//读索引
int wr_idx=1;//写索引

pthread_mutex_t mutex;//互斥
sem_t sem_full;//控制可生产的个数
sem_t sem_empty;//控制可消费的个数

void* pro(void* arg)
{
  int id=*(int*)arg;
  free(arg);
  while(1)
  {
    sem_wait(&sem_full);
    pthread_mutex_lock(&mutex);
    printf("%d号生产者开始生产%d\n",id,num);
    int i;
    for(i=1;i<=BUFSIZE;i++)
    {
      printf("buf[%d]=%d",i,buf[i]);
      if(wr_idx==i)
        printf("<=====");
      printf("\n");
    }
    sleep(rand()%2);
    buf[wr_idx]=(num++)%(BUFSIZE+1);
    num%=BUFSIZE+1;
    wr_idx=(wr_idx+1)%(BUFSIZE+1);
    printf("%d号生产者生产结束\n",id);
    pthread_mutex_unlock(&mutex);
    sem_post(&sem_empty);
  }
}

void* com(void* arg)
{
  int id=*(int*)arg;
  free(arg);
  while(1)
  {
    sem_wait(&sem_empty);
    pthread_mutex_lock(&mutex);
    printf("%d号消费者开始消费%d\n",id,rd_idx);
    int i;
    for(i=1;i<=BUFSIZE;i++)
    {
      printf("buf[%d]=%d",i,buf[i]);
      if(rd_idx==i)
        printf("=====>");
      printf("\n");
    }
    int r=buf[rd_idx];
    buf[rd_idx]=-1;
    rd_idx=(rd_idx+1)%(BUFSIZE+1);
    sleep(rand()%2);
    printf("%d号消费者消费结束%d\n",id,r);
    pthread_mutex_unlock(&mutex);
    sem_post(&sem_full);
  }
}
int main()
{
  pthread_t tid[PRO_COUNT+COM_COUNT];
  //初始化
  pthread_mutex_init(&mutex,NULL);
  sem_init(&sem_full,0,BUFSIZE);
  sem_init(&sem_empty,0,0);

  int i=0;
  for(i=0;i<=BUFSIZE;i++)
    buf[i]=-1;
  //创建生产者线程
  for(i=0;i<PRO_COUNT;i++)
  {
    int* p=(int*)malloc(sizeof(int));
    *p=i+1;
    pthread_create(&tid[i],NULL,pro,(void*)p);
  }
  //创建消费者线程
  for(i=0;i<COM_COUNT;i++)
  {
    int *p=(int*)malloc(sizeof(int));
    *p=i+1;
    pthread_create(&tid[i+PRO_COUNT],NULL,com,(void*)p);
  }
  //等待
  for(i=0;i<PRO_COUNT+COM_COUNT;i++)
  {
    pthread_join(tid[i],NULL);
  }

  //销毁
  sem_destroy(&sem_empty);
  sem_destroy(&sem_full);
  pthread_mutex_destroy(&mutex);
}

执行结果:

3号生产者开始生产1
buf[1]=-1<=====
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=-1
3号生产者生产结束
2号生产者开始生产2
buf[1]=1
buf[2]=-1<=====
buf[3]=-1
buf[4]=-1
buf[5]=-1
2号生产者生产结束
2号生产者开始生产3
buf[1]=1
buf[2]=2
buf[3]=-1<=====
buf[4]=-1
buf[5]=-1
2号生产者生产结束
1号消费者开始消费1
buf[1]=1=====>
buf[2]=2
buf[3]=3
buf[4]=-1
buf[5]=-1
1号消费者消费结束1
3号消费者开始消费2
buf[1]=-1
buf[2]=2=====>
buf[3]=3
buf[4]=-1
buf[5]=-1
3号消费者消费结束2
3号生产者开始生产4
buf[1]=-1
buf[2]=-1
buf[3]=3
buf[4]=-1<=====
buf[5]=-1
3号生产者生产结束
3号生产者开始生产5
buf[1]=-1
buf[2]=-1
buf[3]=3
buf[4]=4
buf[5]=-1<=====
3号生产者生产结束
1号消费者开始消费3
buf[1]=-1
buf[2]=-1
buf[3]=3=====>
buf[4]=4
buf[5]=5
1号消费者消费结束3
1号消费者开始消费4
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=4=====>
buf[5]=5
1号消费者消费结束4
2号消费者开始消费5
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=5=====>
2号消费者消费结束5
2号生产者开始生产0
buf[1]=-1
buf[2]=-1
buf[3]=-1
buf[4]=-1
buf[5]=-1
2号生产者生产结束

符合预期结果。。。

猜你喜欢

转载自blog.csdn.net/shidantong/article/details/81449031