个人复习时自己的理解。。。。。。。。。。。。。。。。。。。。。。。。
1,问题一,当生产者生产了一个产品,消费者去消费,再消费时导致下溢
2,解决问题一: 通过条件变量解决 当没有库存时,消费者再去消费时导致下溢问题
3, 当有多个消费者多个生产者时,也会出现上溢或者下溢的问题,当生产者满了,睡入,当消费者呼叫生产者,
在生存者拿到锁之间 有时间间隙 有可能被其他生产者拿到锁,然后这个生产者继续生产,就会出现上溢
------- 消费者同理, 把if->while 解决问题
1,当生产者生产了一个产品,消费者去消费,再消费时导致下溢
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#define MAX_STOCK 20 //仓库容量
char g_storage=0; //当前库存
pthread_mutex_t g_mtx=PTHREAD_MUTEX_INITIALIZER; /互斥锁声明并初始化
/* 显示库存,op--存货还是提货,prod--存了什么货或者提了声明货 */
void show(const char* who,const char* op,char prod){
printf("%s:“,who);
size_t i;
for(i=0;i<g_stock;++i)
printf("%c",g_storage[i]); // 遍历下库存
printf("%s%c\n",op,prod); //查看下情况
}
/* 生产者 线程 */
void *producer(void* arg){
const char* who=(const char*)arg;
for(;;){ // 生产者无限生产产品
pthread_mutex_lock(&g_mtx); //上锁
char prod='A'+rand()%26; // 随机生产一个字符产品 ,入库
show(who,"<-",prod); // 显示下入库的产品
g_storage[g_stock++]=prod; //入库,并选择第二个产品
pthread_mutex_unlock(&g_mtx); //解锁
usleep((rand()%100)*1000); /* 为了查看结果,给了一个随机的延迟时间,生产有时快有时慢
}
return NULL;
}
/* 消费者线程 */
void *customer(void* arg){
const char* who=(const char*)arg;
for(;;){ //消费者无限消费
pthread_mutex_lock(&g_mtx);
char prod=g_storage[--g_stock]; //消费者提取了一个产品,对当前的库存量减一个
show(who,"->",prod); //显示提取的产品
pthread_mutex_unlock(&g_mtx);
usleep((rand()%100)*1000);
}
return NULL;
}
int main(){
srand(time(NULL));
pthread_t tid;
pthread_create(&tid,NULL,producer,"生产者");
pthread_create(&tid,NULL,customer,"消费者");
getchar(); //不让主进程结束
return 0;
}
..............................................................................................................................
2,解决问题一: 通过条件变量解决 当没有库存时,消费者再去消费时导致下溢问题
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<pthread.h>
#define MAX_STOCK 20 //仓库容量
char g_storage=0; //当前库存
pthread_mutex_t g_mtx=PTHREAD_MUTEX_INITIALIZER; //斥锁声明并初始化
pthread_cond_t g_full=PTHREAD_COND_INITIAIZER; //条件变量 满仓
pthread_cond_t g_empty=PTHREAD_COND_INITIAIZER; //条件变量 空仓
/* 显示库存,op--存货还是提货,prod--存了什么货或者提了声明货 */
void show(const char* who,const char* op,char prod){
printf("%s:“,who);
size_t i;
for(i=0;i<g_stock;++i)
printf("%c",g_storage[i]); // 遍历下库存
printf("%s%c\n",op,prod); //查看下情况
}
/* 生产者 线程 */
void *producer(void* arg){
const char* who=(const char*)arg;
for(;;){ // 生产者无限生产产品
pthread_mutex_lock(&g_mtx); //上锁
if(g_stock>=MAX_STOCK){ // 当前库存大于或等于最大库存时
/*当满了,让生产者睡入条件变量,并开锁,让消费者可以消费,等待消费者叫醒 */
printf("\033[;;32m%s: 满仓!\033[0m\n",who); // 以某种颜色打印下结果
pthread_cond_wait(&g_full,&g_mtx);
}
char prod='A'+rand()%26; // 随机生产一个字符产品 ,入库
show(who,"<-",prod); // 显示下入库的产品
g_storage[g_stock++]=prod; //入库,并选择第二个产品
pthread_mutex_unlock(&g_mtx); //解锁
pthread_cond_signal(&g_empty); //唤醒在睡眠在条件变量(empty)中的消费者
useep((rand()%100)*1000); /* 为了查看结果,给了一个随机的延迟时间,生产有时快有时慢
}
return NULL;
}
/* 消费者线程 */
void *customer(void* arg){
const char* who=(const char*)arg;
for(;;){ //消费者无限消费
pthread_mutex_lock(&g_mtx);
if(!g_stock){
/* 当空了,让消费者睡入g_empty条件变量,并开锁,让生产者生产 等待叫醒*/
printf("\003[;;31m%s:空仓! \033[0m\n",who);
pthread_cond_wait(&g_empty,&g_mtx);
}
char prod=g_storage[--g_stock]; //消费者提取了一个产品,对当前的库存量减一个
show(who,"->",prod); //显示提取的产品
pthread_cond_signal(&g_full); //唤醒在g_full睡眠的生产者,生产者并得到锁
pthread_mutex_unlock(&g_mtx);
usleep((rand()%100)*1000);
}
return NULL;
}
int main(){
srand(time(NULL));
pthread_t tid;
pthread_create(&tid,NULL,producer,"生产者");
pthread_create(&tid,NULL,customer,"消费者");
getchar(); //不让主进程结束
return 0;
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
3, 当有多个消费者多个生产者时,也会出现上溢或者下溢的问题,当生产者满了,睡入,当消费者呼叫生产者,
在生存者拿到锁之间 有时间间隙 有可能被其他生产者拿到锁,然后这个生产者继续生产,就会出现上溢
------- 把if->while 解决问题
其中的 pthread_cond_signal(/*条件变量名*/ 可以换成 pthread_cond_broadcast(/*条件变量名*/)
int main(){
srand(time(NULL));
pthread_t tid;
pthread_create(&tid,NULL,producer,"生产者1");
pthread_create(&tid,NULL,producer,"生产者2");
pthread_create(&tid,NULL,producer,"生产者1");
pthread_create(&tid,NULL,customer,"消费者2");
pthread_create(&tid,NULL,customer,"消费者3");
getchar(); // 不让主进程结束
return 0;
}