生产者消费者模型

       生产者消费者模型是经典的模型,我们都知道,在实际的软件开发中,某个模块负责生产数据,某个模块负责处理数据,产生数据的模块,就形象地成为生产者,而处理数据的模块,被称为消费者。

       我们知道,该模式还需要一个缓冲区处于生产者和消费者之间,作为一个中介,生产者把数据放入缓冲区,而消费者从缓冲区取出数据。

       我们下面基于条件变量和互斥锁,写一个生产者消费者模型的例子:

代码如下:

   #include <stdio.h> 
   #include <stdlib.h> 
   #include <malloc.h> 
   #include <pthread.h> 
    
   typedef int data_type; 
   typedef int* data_type_p; 
    
   pthread_cond_t cond; 
   pthread_mutex_t lock; 
   
  typedef struct node 
  { 
      data_type _data; 
      struct node *next; 
  }node_t,*node_p,**node_pp; 
  node_p head=NULL; 
   
  static node_p buy_node(data_type data) 
  { 
      node_p tmp=(node_p)malloc(sizeof(node_t)); 
      if(tmp) 
      { 
          tmp->_data=data; 
          tmp->next=NULL; 
          return tmp; 
      } 
      return NULL; 
  } 
  
  void init_list(node_pp headp)
  {
      *headp=buy_node(0);
  }
  void push_node(node_p list,data_type data)
  {
      node_p tmp=buy_node(data);
      node_p tail=list;
      while(tail->next)
      {
          tail=tail->next;                                                                                                                                            
      }
      tail->next=tmp;
  }
  
  void delete_node(node_p tmp)
  {
      if(tmp)
      {
          free(tmp);
          tmp=NULL;
      }
  }
  
  int pop_node(node_p list,data_type_p data_p)
  {
      if(NULL==list->next)
      {
          *data_p=-2;
          return -2;
      }
      else
      {
          node_p tmp=list->next;
          list->next=tmp->next;
          *data_p=tmp->_data;
          delete_node(tmp);
      }
      return 0;
  } 
  void show_list(node_p list)
  {
      node_p start=list->next;
      while(start)
      {                                                                                                                                                               
          printf("%d ",start->_data);
          fflush(stdout);
          start=start->next;
      }
      printf("\n");
  }
  
  void *product(void *arg)
  {
      int i=0;
      while(1)
      {
          pthread_mutex_lock(&lock);
          printf("product data:%d\n",i);
          push_node(head,i++);
          pthread_mutex_unlock(&lock);
          printf("product done,wake up consumer...\n");
          pthread_cond_signal(&cond);
          sleep(3);
      }
 }
 
 void *consumer(void *arg)
 {
     data_type _data;
     while(1)
     {
         pthread_mutex_lock(&lock);
         while (-2==pop_node(head,&_data))
         {
             pthread_cond_wait(&cond,&lock);
         }
         printf("consumer data:%d\n",_data);                                                                                                              
         pthread_mutex_unlock(&lock);
         sleep(1);
     }
 }
 
 int main()
 {
     init_list(&head);
     pthread_cond_init(&cond,NULL);
     pthread_mutex_init(&lock,NULL);
 
     pthread_t tid1,tid2;
     pthread_create(&tid1,NULL,product,NULL);
     pthread_create(&tid2,NULL,consumer,NULL);
 
     pthread_join(tid1,NULL);
     pthread_join(tid2,NULL);
     return 0;
  }
  
  从上面的代码我们可以看到,我们用一个链表作为缓冲区,生产者生产的数据尾插到链表里,消费者从链表头取数据。
  运行结果如下:

wKioL1cblV7zJURQAAA8kghRJjs879.png

    从结果我们可以看到,生产者消费者之间很好的实现了同步与互斥功能,生产者生产一个数据,消费者就消费一个数据。