线程——生产者消费者模型

在生活中,我们经常去超市买东西,这里涉及到三个事物:我们、超市、供货商

我们相当于消费者,超市相当于交易场所,供货商相当于生产者

对于生产者消费者模型我们总结为3 2 1原则:

·3中关系

·2中角色

·1个交易场所

三种关系:

(1)生产者——生产者

        假设所有的供货商都生产同一种产品,而超市只能由一家供货商供货,他们之间肯定互相竞争这个名额,那么可想而知他们之间存在着互斥关系 

(2)消费者——消费者

        如果现在超市中只有一件商品了,而所有的消费者就想去拥有这款商品,同样他们就会去互相竞争,也就是存在着互斥关系

(3)生产者——消费者

        如果超市的货架上一件商品都没有我们可以消费吗?在想想超市的货架上面商品都摆的满满的,供货商还会继续摆商品吗?答案是不会,所以消费者必须等生产者生产出商品才能消费,而生产者必须等到消费者消费商品之后才能继续生产,这是典型的同步关系。同样的生产者和消费者之间还具有着互斥关系 。生产者把商品放到货架上的时候消费者不能去消费,必须等生产者放完才可以消费,而在消费者把商品从货架上拿走的时候生产者不能去放商品,必须等消费者完全拿走之后才可以放。

  1 #include<stdio.h>
  2 #include<stdlib.h>
  3 #include<unistd.h>
  4 #include<pthread.h>
  5 #include<time.h>
  6 
  7 #define CONSUMERS_COUNT 2
  8 #define PRODUCERS_COUNT 2
  9 
 10 struct msg{
 11     struct msg *next;
 12     int num;
 13 };
 14 struct msg *head = NULL;
 15 
 16 pthread_cond_t cond;//条件变量
 17 pthread_mutex_t mutex;//锁
 18 pthread_t threads[CONSUMERS_COUNT + PRODUCERS_COUNT];
 19 
 20 void *consumer(void *p)
 21 {
 22     int num = *(int*)p;
 23     free(p);
 24     struct msg *mp;
 25     for(;;){
 26         pthread_mutex_lock(&mutex);//上锁
 27         while(head == NULL){
 28             printf("%d begin wait a condition...\n",num);
 29             pthread_cond_wait(&cond,&mutex);
 30         }
 31         printf("%d end wait a condition...\n",num);
 32         printf("%d begin consume product...\n",num);
 33         mp = head;
 34         head = mp->next;
 35         pthread_mutex_unlock(&mutex);//解锁
 36         printf("Consume %d\n",mp->num);
 37         free(mp);
 38         printf("%d end consume product...\n",num);
 39         sleep(rand()%5);
 40     }
 41 }
 42 void *producer(void *p)
 43 {
 44     struct msg *mp;
 45     int num = *(int*)p;
 46     free(p);
 47     for(;;){
 48         printf("%d begin produce prodect...\n",num);
 49         mp = (struct msg*)malloc(sizeof(struct msg));
 50         mp->num = rand()%1000 + 1;
 51         printf("produce %d\n",mp->num);
 52         pthread_mutex_lock(&mutex);
 53         mp->next = head;
 54         head = mp;
 55         printf("%d end produce product...\n",num);
 56         pthread_cond_signal(&cond);
 57         pthread_mutex_unlock(&mutex);
 58         sleep(rand()%5);
 59 
 60     }
 61 }
 62 
 63 int main()
 64 {
 65     srand(time(NULL));
 66 
 67     pthread_cond_init(&cond,NULL);//初始化条件变量
 68     pthread_mutex_init(&mutex,NULL);//初始化锁
 69 
 70     int i;
 71     for(i = 0;i < CONSUMERS_COUNT;i++){
 72         int *p = (int*)malloc(sizeof(int));
 73         *p = i;
 74         pthread_create(&threads[i],NULL,consumer,(void*)p);//创建消费者线程
 75     }
 76 
 77     for(i = 0;i < PRODUCERS_COUNT; i++){
 78         int *p = (int*)malloc(sizeof(int));
 79         *p = i;
 80         pthread_create(&threads[CONSUMERS_COUNT + i],NULL,producer,(void*)p);//创建生产者线程
 81     }
 82 
 83     for(i = 0; i < CONSUMERS_COUNT + PRODUCERS_COUNT; i++){
 84         pthread_join(threads[i],NULL);//线程等待
 85     }
 86     pthread_mutex_destroy(&mutex);
 87     pthread_cond_destroy(&cond);
 88 }

上述生产者消费者模型是利用单链表模拟的交易场所实现的。我们还可以基于环形队列实现生产者消费者模型。

环形队列的概念:环形队列是一段连续的空间,我们很容易就可以想到数组也是一段连续的空间,所以利用数组和模运算就很容易模拟环形队列了。


基于环形队列的生产者消费者模型需要遵守的原则:

1、生产者必须走在消费者之前

2、生产者虽然先走,但不能套圈消费者

3、当队列为空时,生产者先走

     当队列为满时,消费者先走


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值