【C语言】链表实现消费者生产者问题

这里的代码围绕一个生产者和一个消费者来分析,生产者生产一个产品,消费者才能使用一个产品,消费者和生产者是同步关系。

一:不加同步互斥锁

pthre#include<stdio.h>  

#include<stdlib.h>

#include<pthread.h>

typedef struct _Node{
    struct _Node* next;
    int data;
}node_t,*node_p,**node_pp;//创建结构体

node_p alloc_node(int x){ //为节点开辟空间
    node_p p=(node_p)malloc(sizeof(node_t));
    if(!p){
        perror("malloc");
        exit(1);
    }   
   p->data=x;
   p->next=NULL;
   return p;
}
void init_list(node_pp h){ //初始化链表
    if(h==NULL){
        return;
    }   
    *h=alloc_node(0);
}

void list_push(node_p h,int x){ //插入节点(生产者生产产品放入链表中)
    node_p p=alloc_node(x);
    p->next=h->next;
    h->next=p;
}


int is_empty(node_p head){//判断链表是否为空
    return head->next==NULL?1:0;
}
void list_pop(node_p head,int* x){//删除节点(在这里是消费者消费产品)
    if(!is_empty(head)){
        node_p p=head->next;
        *x=p->data;
        head->next=p->next;
        free(p);
    }
}
void list_destroy(node_p h){//销毁链表
    int x;
    while(!is_empty(h)){
       list_pop(h,&x) ;
    }
    free(h);
}


void show_list(node_p h){//打印链表
    if(!is_empty(h)){
        node_p p=h->next;
        while(p){
            printf("%d ",p->data);
            p=p->next;
        }
        printf("\n");
    }
}
void* consumer(void* arg){//消费者代码
    node_p head=(node_p)arg;
    while(1){
        int data;
       list_pop(head,&data);
       printf("consumer done! data is:%d\n",data);
        sleep(1);
    }
}
void* product(void* arg){//生产者代码
     while(1){
         node_p head=(node_p)arg;
         if(is_empty(head)){
             int data;
             data=rand()%100+1;
            list_push(head,data);
             printf("product done! data is:%d\n",data);
         }else{
             printf("product waiting!\n");
         }
            sleep(2);
}
}
int main(){

   node_p head;

   init_list(&head);


   pthread_t c,p;
   pthread_create(&c,NULL,consumer,(void*)head);
   pthread_create(&p,NULL,product,(void*)head);

   pthread_join(c,NULL);
   pthread_join(p,NULL);
   list_destroy(head);
}

结果:



由结果可以分析两种情况:

1>消费者消费的快,而生产者慢,若不加同步互锁,消费者则反复消费唯一的一个产品。

2>消费者慢,生产者快,若不加同步互斥锁,节点会越来越多,消费者取得永远都是最近生产的一个产品。

二:添加同步互斥锁


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


pthread_mutex_t lock;
pthread_cond_t cond;

typedef struct _Node{
    struct _Node* next;
    int data;
}node_t,*node_p,**node_pp;


node_p alloc_node(int x){ 
    node_p p=(node_p)malloc(sizeof(node_t));
    if(!p){
        perror("malloc");
        exit(1);
    }   

   p->data=x;
   p->next=NULL;
   return p;
}
void init_list(node_pp h){ 
    if(h==NULL){
        return;
    }   
    *h=alloc_node(0);
}


void list_push(node_p h,int x){ 
    node_p p=alloc_node(x);
    p->next=h->next;
    h->next=p;
}

int is_empty(node_p head){
    return head->next==NULL?1:0;
}
void list_pop(node_p head,int* x){ 
    if(!is_empty(head)){
        node_p p=head->next;
        *x=p->data;
        head->next=p->next;
        free(p);
    }   
}
void list_destroy(node_p h){ 
    int x;
    while(!is_empty(h)){
       list_pop(h,&x) ;
    }   
    free(h);
}

void show_list(node_p h){ 
    if(!is_empty(h)){
        node_p p=h->next;
        while(p){
            printf("%d ",p->data);
            p=p->next;
        }
        printf("\n");
    }
}
void* consumer(void* arg){
    node_p head=(node_p)arg;
    while(1){
       pthread_mutex_lock(&lock);
       if(!is_empty(head)){
           int data;
           list_pop(head,&data);
           printf("consumer done! data is:%d\n",data);
       }else{
           printf("consumer waiting!\n");
           pthread_cond_wait(&cond,&lock);
       }
       pthread_mutex_unlock(&lock);
       sleep(3);
    }
}
void* product(void* arg){
    while(1){
        node_p head=(node_p)arg;
        if(is_empty(head)){//通过判断来避免消费者慢生产者快的问题
            int data;
            data=rand()%100+1;
            pthread_mutex_lock(&lock);
            list_push(head,data);
            pthread_cond_signal(&cond);
            printf("product done! data is:%d\n",data);
            pthread_mutex_unlock(&lock);
        }else{
            printf("product waiting!\n");
        }
        sleep(1);
    }
}
int main(){

   node_p head;
   init_list(&head);
   pthread_mutex_init(&lock,NULL);
   pthread_cond_init(&cond,NULL);

   pthread_t c,p;
   pthread_create(&c,NULL,consumer,(void*)head);
   pthread_create(&p,NULL,product,(void*)head);

   pthread_join(c,NULL);                                                                                                                                                                                                                                    
   pthread_join(p,NULL);
   list_destroy(head);
   pthread_mutex_destroy(&lock);
   pthread_cond_destroy(&cond);
}

结果:



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值