这是一个经典的猴子吃桃子的问题的实现(生产-消费者问题)
有一棵桃树和一只猴子,开始的时候桃树上没有桃子,然后开始一个一个的长,每长一个猴子就吃一个,猴子吃了之后再长一个,又被猴子吃掉,猴子需要吃7个桃子,才能吃饱。编写程序模拟这个猴子吃桃子的过程。
一看这肯定是两个线程,一个是桃树长桃子,一个是猴子吃桃子,归根是一个生产者和消费者的问题。
注意事项
互斥锁用起来比较简单,条件变量会有点东西
条件变量其实就是一种通知,等待机制,要学会用这种机制去解决问题,语法也是相当之简单的,看下面这个代码就可以了
注意的是pthread_cond_wait 这个里面,可以理解是把锁借出去了的感觉~
代码
#include <stdio.h>
#include <pthread.h>
#define COUNT 7 // 一共需要吃多少桃子
static int int_grow_number = 0; // 已经长了多少桃子
static int int_eat_number = 0; // 已经吃了多少桃子
pthread_mutex_t lock;
pthread_cond_t can_eat;// 猴子可以吃桃子了。
pthread_cond_t can_grow; // 桃树需要长桃子
void *eat(void *data)
{
int n;
while(1)
{
pthread_mutex_lock(&lock);
if(int_grow_number == int_eat_number){
pthread_cond_wait(&can_eat, &lock); // 已经吃完所有的桃子
}
if(int_grow_number == -1){
printf("本猴子已经吃饱\n");
}else{
int_eat_number ++;
printf("猴子正吃第 (%d) 个桃子\n",int_eat_number);
}
sleep(1);
pthread_cond_signal(&can_grow); //通知桃树长桃子
pthread_mutex_unlock(&lock);
if(int_grow_number == -1)
break;
};
return NULL;
}
void *grow(void *data)
{
while (1)
{
pthread_mutex_lock(&lock);
if(int_grow_number >= int_eat_number+1){
pthread_cond_wait(&can_grow, &lock); // 等待猴子吃桃子
}
if(int_grow_number >= COUNT){ // 检查猴子是否吃饱了
int_grow_number = -1; // 没得吃了
printf("本次喂食结束 \n");
}else{
int_grow_number ++;
printf("桃树正长第 (%d) 个桃子 \n",int_grow_number);
}
pthread_cond_signal(&can_eat); // 通知猴子可以吃桃子
pthread_mutex_unlock(&lock);
if (int_grow_number == -1)
break;
}
return NULL;
}
int main(void)
{
pthread_t th_peach, th_monkey;
void *retval;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&can_eat, NULL);
pthread_cond_init(&can_grow, NULL);
pthread_create(&th_peach, NULL, grow, 0);
pthread_create(&th_monkey, NULL,eat, 0);
/* 等待猴子吃饱,结束*/
pthread_join(th_peach, &retval);
pthread_join(th_monkey, &retval);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&can_eat);
pthread_cond_destroy(&can_grow);
return 0;
}