生产者消费者问题实现

Linux c系统编程多线程之生产者消费者问题
使用条件变量实现生产者-消费者问题:
  • 商品使用一个链式队列描述,初始商品个数为8,最大商品个数是10个,不同的商品用不同的随机数区分

  • 生产者有3个线程,每个线程每3秒产生一个商品

  • 消费者有2个线程,先睡眠5秒,每个线程每1秒消耗一个商品

显示每次生产和消费的商品的随机编号。

思考:1.多线程并发访问造成的资源竞争问题—>可以使用互斥锁进行解决,A线程在访问共享资源的时候先上锁,这是若有其他线程B访问共享资源就会陷入阻塞,直到A访问完毕并且释放锁之后,B线程才能访问。

​ 2.该题目设计两个同步问题:使用条件变量

  • ​ 生产 - > 消费

    当生产者生产的产品数量达到上限时,这是会陷入等待,需要消费者线程消费之后才能生产

    ​ 消费 -> 生产

​ 3.虚假唤醒问题: 使用条件wait;

while(number >= 0){
	pthread_cond_wait(&cond,&mutex);
}

代码如下:

#include <func.h>

typedef struct node_s{
    int val;
    struct node_s* next;
}node_t;

typedef struct{
    node_t* head;
    node_t* tail;
    int size;
}Queue;

typedef struct shrerRes_s{
    pthread_mutex_t mutex;
    pthread_cond_t cond;
    Queue* que;
    int cnt;
}shareRes_t;

void initQueue(Queue* que);
bool isEmpty(Queue* que);
void pushQueue(Queue* que, int ele);
void popQueue(Queue* que, int* ele);
void printQueue(Queue* que);


void* productor(void* arg){
    
    shareRes_t* sRs = (shareRes_t*)arg;
    while(1){
        pthread_mutex_lock(&sRs->mutex);
        while(sRs->cnt >= 10){
            pthread_cond_wait(&sRs->cond,&sRs->mutex);
        }

        //生产
        int id = rand()%100 + 1;
        pushQueue(sRs->que,id);
        sRs->cnt++;
        printf("productor, id:%d\n",id);
        printQueue(sRs->que);

        pthread_cond_broadcast(&sRs->cond);
        pthread_mutex_unlock(&sRs->mutex);
        sleep(3);
    }

    pthread_exit(NULL);
}

void* consumer(void* arg){
    sleep(5);
    shareRes_t* sRs = (shareRes_t*)arg;
    while(1){
        pthread_mutex_lock(&sRs->mutex);
        while(sRs->cnt <= 0){
            pthread_cond_wait(&sRs->cond,&sRs->mutex);
        }

        //生产
        int id;
        popQueue(sRs->que,&id);
        printf("consumer, id:%d\n",id);
        printQueue(sRs->que);
        sRs->cnt--;

        pthread_cond_broadcast(&sRs->cond);
        pthread_mutex_unlock(&sRs->mutex);
        sleep(1);
    }
    pthread_exit(NULL);

}
int main(int argc, char* argv[])
{
    shareRes_t sRs;
    sRs.que = (Queue*)malloc(sizeof(Queue));
    pthread_mutex_init(&sRs.mutex,NULL);
    pthread_cond_init(&sRs.cond,NULL);
    sRs.cnt = 0;
    srand(time(NULL));
    pthread_t pt1,pt2,pt3;
    pthread_t ct1,ct2;
    //生产八个产品
    for(int i = 0; i < 8; i++){
        pushQueue(sRs.que,rand()%100+1);
        sRs.cnt++;
    }
    pthread_create(&pt1,NULL,productor,&sRs);
    pthread_create(&pt2,NULL,productor,&sRs);
    pthread_create(&pt3,NULL,productor,&sRs);
    pthread_create(&ct1,NULL,consumer,&sRs);
    pthread_create(&ct2,NULL,consumer,&sRs);

    pthread_join(pt1,NULL);
    pthread_join(pt2,NULL);
    pthread_join(pt3,NULL);
    pthread_join(ct1,NULL);
    pthread_join(ct2,NULL);
    
    return 0;
}


void initQueue(Queue* que){
    que->head = NULL;
    que->tail = NULL;
    que->size = 0;
}

bool isEmpty(Queue* que){
    return que->head == NULL;
}

void pushQueue(Queue* que, int ele){
    node_t* newNode = (node_t*)malloc(sizeof(node_t));
    if(newNode == NULL){
        fprintf(stderr,"%s\n","allocate memary failed\n");
        exit(1);
    }

    newNode->next = NULL;
    newNode->val = ele;

    if(que->head == NULL){
        que->head = que->tail = newNode;
    }else{
        que->tail->next = newNode;
        que->tail = que->tail->next;
    }
    que->size++;
}
void popQueue(Queue* que, int* ele){
    if(isEmpty(que)){
        printf("Queue is empty\n");
        return;
    }

    node_t* tmp = que->head;
    *ele = tmp->val;
    if(que->head == que->tail){
        que->head = que->tail = NULL;
    }else{
        que->head = que->head->next;
    }

    free(tmp);
    que->size--;
}


void printQueue(Queue* que){
    node_t* head = que->head;
    while(head){
        printf("%d ",head->val);
        head = head->next;
    }
    printf("\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值