操作系统模拟生产者-消费者问题

@[TOC]生产者-消费者问题

生产者-消费者问题

生产者-消费者问题:
一群生产者在生产消息,并将此消息提供给消费者去消费。它们中间设了具有N个缓存区的缓冲池,生产者每次可将生产的消息放入一个缓存区内,消费者每次可将一个缓存区内的消息拿出来消费。但这个过程有两个条件:任何一方操作一个缓冲区时不能有其它同时对该缓冲区进行操作;只有当缓冲区还有空余,生产者才能生产,只有当缓冲区至少有一个产品,消费者才能从中取出来消费。这里两个条件分别对应了互斥和同步。
在这里插入图片描述
如上图所示便是生产者-消费者模型,它是利用存储中介隔离生产者和消费者的交互,相比直通而言,它的好处在于:不必相互等待,提高运行效率。

实现思路

运用所学的线程互斥锁和条件变量来实现此模型。
对于生产者而言:
(1)先上锁
(2)如果存储中介中元素大于或等于存储最大数量,则不需要生产,则阻塞于此,释放锁;反之,则生产,
(3)在收到可生产条件信号之后,便唤醒进程,判断是否可生产,(可能只需要生产一件,但唤醒了多个线程)
(4)生产结束后,释放锁

对于消费者者而言:
(1)先上锁
(2)如果存储中介中元素小于或等于0,则不能消费,则阻塞于此,释放锁;反之,则消费,
(3)在收到可消费条件信号之后,便唤醒进程,判断是否可消费,(可能只能消费一件,但唤醒了多个线程)
(4)消费结束后,释放锁

实现代码

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>

typedef struct Store{ //存储缓冲区结构体
    char things[10];
    int cnt;
}Store;

Store s;
pthread_mutex_t mutex; //互斥锁类型
pthread_cond_t notfull; //缓冲区未满(可生产)信号
pthread_cond_t notempty;//缓冲区未空(可消费)信号

void *proc(void *arg) { //product 生产
    while(1){
        pthread_mutex_lock(&mutex);  //上锁
        while(s.cnt >= 10) { //必须用while 不能用if
            pthread_cond_wait(&notfull,&mutex); //等待 并释放锁
        }
        char c = rand()%26+'A';
        s.things[s.cnt++] = c;
        size_t i;
        for(i = 0;i < s.cnt;i++) {
            printf("%c ",s.things[i]);
        }
        printf("\n");
        printf("放入:%c\n",c);
        pthread_cond_signal(&notempty); //生产后必定可消费 发出可消费条件信号
        pthread_mutex_unlock(&mutex); // 解锁
        usleep(rand()%100000);
    }
}
 void *cust(void *arg) { //消费
     while(1){
         pthread_mutex_lock(&mutex);//上锁
         while(s.cnt <= 0) {
             pthread_cond_wait(&notempty,&mutex);
         }
         size_t i;
         for(i = 0;i < s.cnt;i++) {
             printf("%c ",s.things[i]);
         }
         printf("\n");
         char c = s.things[--s.cnt];
         printf("取出:%c\n",c);
         pthread_cond_signal(&notfull);//消费后必定可生产 发出可生产信号
         pthread_mutex_unlock(&mutex);//解锁
         usleep(rand()%100000);
     }
 }
 
 int main() {
     srand(time(NULL));
     pthread_t ids[6];
     pthread_mutex_init(&mutex,NULL); // 互斥量初始化
     pthread_cond_init(&notfull,NULL); // 条件变量初始化
     pthread_cond_init(&notempty,NULL);
     size_t i;
     for(i = 0;i < 6;i++) {
         if(i%2 == 0) {
             pthread_create(&ids[i],NULL,proc,NULL);
         }else{
             pthread_create(&ids[i],NULL,cust,NULL);
         }
     }
     getchar();
     return 0;
 }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值