【经典面试题】生产者消费者模型

条件变量

条件变量是利用线程间共享的全局变量进行同步的一种机制。主要包括两个动作:一个线程等待“条件变量的条件成立”而挂起,另一个线程让“条件成立(给出条件成立信号)”

作用:为了防止竞争

注意事项:条件变量的使用总是和一个互斥锁结合在一起

1.pthread_cond_t cond;    //定义条件变量的全局变量

2.pthread_cond_init(&cond,NULL)  //初始化

3.pthread_cond_wait(&cond,&mutex) //等待条件  mutex为互斥量   阻塞时将mutex置成1,返回时,将mutex恢复程原样

4.pthread_cond_signal(&cond)//发送信号让等待条件满足

5.pthread_cond_destroy(&cond)//销毁条件变量

案例:一秒钟打印一次激活

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 pthread_cond_t cond;
  5 pthread_mutex_t mutex;
  6 void *r1(void *arg)                                                                                                                                      
  7 {
  8     while(1)
  9     {
 10         pthread_cond_wait(&cond,&mutex);
 11         printf("激活!!\n");
 12     }
 13 }
 14 void *r2(void *arg)
 15 {
 16     while(1)
 17     {
 18         sleep(1);
 19         pthread_cond_signal(&cond);
 20     }
 21 }
 22 int main()
 23 {
 24     pthread_t t1,t2;
 25     pthread_cond_init(&cond,NULL);
 26     pthread_mutex_init(&mutex,NULL);
 27     pthread_create(&t1,NULL,r1,NULL);
 28     pthread_create(&t2,NULL,r2,NULL);
 29     pthread_join(t1,NULL);
 30     pthread_join(t2,NULL);
 31     pthread_cond_destroy(&cond);
 32     pthread_mutex_destroy(&mutex);
 33 }

生产者消费者模型

生产者生产物品消费者必须要等生产者的物品生产后才能进行消费,当出现多个生产者多个消费者的时候就需要用互斥锁来进行控制,避免产生混乱,具体如图:

具体使用:

wait使用规范:

pthread_mutex_lock(&mutex) //在锁的环境内使用

while(条件不满足)  //用while的原因:wait可以被pthread_cond_signal唤醒也可以被信号唤醒

          pthread_cond_wait(&cond,&mutex)

pthread_mutex_unlock(&mutex)

消费者:

pthread_mutex_lock(&mutex)

pthread_cond_signal(&cond)//有线程在wait就通知线程返回,没有线程在等待,signal信号被丢掉

pthread_mutex_unlock(&mutex)

具体代码:

  1 #include<stdio.h>                                                                                                                                                                                            
  2 #include<stdlib.h>
  3 #include<pthread.h>
  4 #include<unistd.h>
  5 #define CONSUMERS_COUNT 2  //定义两个生产者
  6 #define PRODUCERS_COUNT 2  //定义两个消费者
  7 int counter=0;//仓库中产品的个数
  8 pthread_cond_t cond;
  9 pthread_mutex_t mutex;
 10 void *consumer(void *arg)
 11 {
 12     int id=*(int*)arg;
 13     free(arg);
 14     while(1)
 15     {
 16         pthread_mutex_lock(&mutex);
 17         while(counter<=0)
 18         {
 19             printf("%d 消费者线程等待消费\n",id);
 20             pthread_cond_wait(&cond,&mutex);
 21         }
 22         printf("%d消费者线程开始消费\n",id);
 23         counter--;
 24         sleep(rand()%5);//随机设置一个消费时间
 25         printf("%d消费者线程结束消费\n",id);
 26         pthread_mutex_unlock(&mutex);
 27         sleep(rand()%2);
 28     }
 29 }
 30 void *producer(void *arg)
 31 {
 32     int id=*(int*)arg;
 33     free(arg);
 34     while(1)
 35     {
 36         pthread_mutex_lock(&mutex);
 37         printf("%d生产者线程开始生产\n",id);
 38         counter++;
 39         sleep(rand()%6);
 40         printf("%d生产者线程生产产品结束\n",id);
 41         pthread_cond_signal(&cond);
 42         pthread_mutex_unlock(&mutex);
 43         sleep(1);
 44     }
 45 }
 46 int main()
 47 {
 48     srand(getpid());
 49     pthread_t tid[CONSUMERS_COUNT+PRODUCERS_COUNT];
 50     pthread_cond_init(&cond,NULL);
 51     pthread_mutex_init(&mutex,NULL);
 52     int i;
 53     for( i=0;i<CONSUMERS_COUNT;i++)
 54     {
 55         int *p=malloc(sizeof(int));
 56         *p=i;//将获取到的线程号保存
 57         pthread_create(&tid[i],NULL,consumer,p);
 58     }
 59     for( i=0;i<PRODUCERS_COUNT;i++)
 60     {
 61         int *p=malloc(sizeof(int));
 62         *p=i;
 63         pthread_create(&tid[i+CONSUMERS_COUNT],NULL,producer,p);
 64     }
 65     for( i=0;i<CONSUMERS_COUNT+PRODUCERS_COUNT;i++)
 66     {
 67         pthread_join(tid[i],NULL);//线程等待
 68     }
 69     pthread_cond_destroy(&cond);
 70     pthread_mutex_destroy(&mutex);
 71 }                                  

猜你喜欢

转载自blog.csdn.net/enjoymyselflzz/article/details/81946776