生产者与消费者模型

  生产者与消费者模型是一种描述进程间同步与互斥的一个方式,在这个模式下有两类人,一个是不停产生数据的生产者,一个是不停获取数据的消费者,为了效率最高,就必须保持两者之间的同步与互斥。

  为了在生产者与消费者使用mutex保持互斥的前提下,posix版本下还有另外一个函数cond它的作用是在生产者生产出来一个数据时便提醒消费者,而消费者在没东西消费时可以使用cond将自己保持在一个等待生产者信号和关闭锁的状态,当收到信号时将锁打开然后消费。

这是cond的创建与销毁:

       #include <pthread.h>

       int pthread_cond_destroy(pthread_cond_t *cond);
       int pthread_cond_init(pthread_cond_t *restrict cond,
              const pthread_condattr_t *restrict attr);
       pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

cond的发送信号的函数

       #include <pthread.h>

       int pthread_cond_broadcast(pthread_cond_t *cond);//用向所有正在等待该资源产生的进 //程发送信号
       int pthread_cond_signal(pthread_cond_t *cond);//向单个发送

cond的等待函数

       #include <pthread.h>

       int pthread_cond_timedwait(pthread_cond_t *restrict cond,//非阻塞式等待
              pthread_mutex_t *restrict mutex,
              const struct timespec *restrict abstime);
       int pthread_cond_wait(pthread_cond_t *restrict cond,//阻塞式等待
              pthread_mutex_t *restrict mutex);

代码实现:

缓冲区模型为一个头插头删的链表

单个消费者和单个生产者:

  1 #include<stdio.h>
  2 #include<malloc.h>
  3 #include<pthread.h>
  4 
  5 pthread_mutex_t comm = PTHREAD_MUTEX_INITIALIZER;
  6 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
  7 
  8 typedef int data_type;
  9 typedef struct list{
 10     data_type _data;
 11     struct list *_next;
 12 }list;
 13 void init_list(list *head)
 14 {
 15     head->_next=NULL;
 16 }
 17 void push(list *head,data_type data)
 18 {
 19     if(head->_next==NULL)
 20     {
 21         list *tmp=(list*)malloc(sizeof(list));
 22         tmp->_data=data;                                                             
 23         tmp->_next=NULL;
 24         head->_next=tmp;
 25     }
 26     else{
 27         list *tmp=(list*)malloc(sizeof(list));
 28         tmp->_next=head->_next;
 29         tmp->_data=data;
 30         head->_next=tmp;
 31     }
 32 }
 33 
 34 int pop(list *head,data_type*data)
 35 {
 36     if(head->_next==NULL)
 37     {
 38         return -1;
 39     }
 40     else
 41     {
 42         *data=head->_next->_data;
 43         list *tmp=head->_next;
 44         head->_next=tmp->_next;
 45         free(tmp);
 46         return 0;
 47     }
 48 }
 49 
 50 void display_list(list *head)
 51 {
 52     list *tmp=head->_next;
 53     while(tmp!=NULL)
 54     {
 55         printf("%d",tmp->_data);
 56         fflush(stdout);
 57         tmp=tmp->_next;
 58     }
 59 }
 60 list head;
 61 
 62 void * producter(void *arg)
 63 {
 64     int i=0;
 65     while(1)
 66     {
 67         pthread_mutex_lock(&comm);
 68         push(&head,i);
 69         pthread_mutex_unlock(&comm);
 70         printf("producter :%d\n",i++);
 71         pthread_cond_broadcast(&cond);
 72         sleep(1);
 73     }
 74 }
 75 void * constumer(void *arg)
 76 {
 77     data_type data;
 78     sleep(10);
 79     while(1)
 80     {
 81             sleep(1);
 82         pthread_mutex_lock(&comm);
 83         while(pop(&head,&data)<0)
 84         {
 85             pthread_cond_wait(&cond,&comm);
 86             printf("buff is empty\n");
 87         }
 88         printf("constumer :%d\n",data);
 89         pthread_mutex_unlock(&comm);
 90     }
 91 }
 92 int main()
 93 {
 94     init_list(&head);
 95     pthread_t _producter,_constumer;
 96     pthread_create(&_producter,NULL,producter,NULL);
 97     pthread_create(&_constumer,NULL,constumer,NULL);
  98     pthread_join(_producter,NULL);
 99      pthread_join(_constumer,NULL);
100
101
102     return 0;
103 }