可控数量的生产者消费者问题(linux c )

#背景

  自己在实现生产者-消费者问题的时候,发现网上的代码都是无限生产,不存在终止问题.但是如果使用无限生产的代码去改造成生产定量的代码就会出现bug,比如是无法退出,生产数不对,所以我自己写了一个基于linux c的参数控制生产定量与生产者消费者数目的简单程序,分享一下并记录.

#函数介绍

·pthread_cond_wait(&con1,&mutex);//等待条件变量 互斥锁解锁

· pthread_cond_broadcast(&con1);激活所有等待该条件变量的线程

·pthread_cond_signal(&con2);// 激活一个等待该条件变量的线程 调度顺序由内核决定

·pthread_create(&pc[i],NULL,consumer,NULL); //构造线程

·pthread_join(pc[i],&thread_result);// 等待子进程结束

#难点

   要知道pthread_con_wait()无法获取条件变量会阻塞自己.那么当缓存区已满,生产者将会阻塞自己.线程是并发的,由内核调度,所以下一个有可能还是生产者,那么会出现当不止一个生产者阻塞.如果这时达到了生产上限,那么当生产者被唤醒,生产量会继续++,所以判断条件需要在循环内部加入.

  当生产者生产产品期间消费者消耗了已有的所有产品,将会阻塞,由于并发性,那么有可能有不止一个线程阻塞,当此时最后一个生产者停止生产,只会唤醒其中的一个线程,其余线程还会继续阻塞,所以需要使用pthread_cond_broadcast()唤醒所有的消费者线程.

···

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>
pthread_mutex_t mutex;
pthread_cond_t con1;
pthread_cond_t con2;
int num=0;
int sum = 0;
int rum=0;
int n = 0;
#define Maxnum 5 //缓存区大小
int to_int(char *a)
{
int num = 0 ;
for (int  i= 0; a[i]!='\0' ;i++ )
{
int b = (int)(a[i]-'0');
num = num*10+b;

 
}
return num;
}

void *producer(void *args)
{
 while(sum<n)
{
pthread_mutex_lock(&mutex);
if(num>=5)
{
printf("当前无空地\n");
 pthread_cond_wait(&con1,&mutex);//等待条件变量 互斥锁解锁 pthread_cond_broadcast()则激活所有等待线程
 
}
num++;
sum++;
if(sum>n)
{
pthread_mutex_unlock(&mutex);
break;

}


printf("P id :%ld and i print %d\n",pthread_self(),sum);

pthread_cond_signal(&con2);// 激活一个 pthread_cond_broadcast()则激活所有等待线程
pthread_mutex_unlock(&mutex);

}
pthread_cond_broadcast(&con2);
pthread_exit(NULL);
}
void *consumer(void *args)
{
 while(rum<n)
{
pthread_mutex_lock(&mutex);
if(num<=0){
    printf("当前无产品\n");
    pthread_cond_wait(&con2,&mutex);

}
num--;
rum++;
if(rum>n)
{
pthread_mutex_unlock(&mutex);
break;

}


printf("C id :%ld and i print %d\n",pthread_self(),rum);
pthread_cond_signal(&con1);
pthread_mutex_unlock(&mutex);


}
pthread_exit(NULL);
}
int main(int argc ,char *argv[])
{
 n = to_int (argv[1]);

 pthread_t pp[10],pc[10];
int res;
void *thread_result;
for(int i = 0  ;i<to_int(argv[2]);i++ )
{
res =pthread_create(&pp[i],NULL,producer,NULL);
if(res !=0)
{
printf("error1\n") ;
}

}

for(int i =0;i< to_int(argv[3]) ;i++)
{
res =pthread_create(&pc[i],NULL,consumer,NULL);
if(res !=0)
{
printf("error3\n") ;
}

}
for (int i =0 ;i<to_int(argv[2]);i++)
{
res = pthread_join(pp[i],&thread_result);
}
for (int i =0 ;i<to_int(argv[3]);i++)
{
res = pthread_join(pc[i],&thread_result);
}


pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&con1);
pthread_cond_destroy(&con2);
 
return 0;

}

···

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值