PV实现吃水果问题(进程同步)

问题描述:一对夫妇有2个儿子和1个女儿,爸爸买了一袋苹果和一袋橘子,他们决定玩一个游戏来分享这些水果。爸爸在随机的时刻拿一个苹果放在盘子中,妈妈在随机的时刻拿一个橘子放在盘子中,但是盘子中同时最多只能放一个水果。女儿会拿走盘子中的苹果,大儿子和小儿子会交替地拿走盘子中的橘子。

预期达到效果:编写一个程序能够使爸爸线程,妈妈线程,儿子线程,女儿线程正确地执行。程序中输入苹果和橘子的数量,输出并发执行的过程。并统计儿子和女儿吃的水果的数量。

代码如下:

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

//定义信号量
sem_t empty,apple,orange,mutex;//全局变量 

//用于父亲放苹果 
void* Father(void* arg)
{
	int k=0,num=(int)(unsigned long)arg;
	while(k<num) 
	{
		sem_wait(&empty);//观察盘子是否为空 
		k++;
		printf("父亲放入第%d个苹果\n",k);// 父亲放入一个苹果
		sem_post(&apple);//叫醒女儿吃苹果 
       		sleep(5); //休眠5毫秒 
    	}
   	 printf("The apples are finished!\n"); 
}

//用于母亲放橘子
void* Mother(void* arg) 
{
	int k=0,num=(int)(unsigned long)arg;
	while(k<num) 
	{
		sem_wait(&empty);//观察盘子是否为空 
		k++;
		printf("母亲放入第%d个橘子\n",k);// 母亲放入一个橘子 
		sem_post(&orange);//叫醒儿子吃橘子 
        		sleep(5);  //休眠5毫秒
	}
	printf("The oranges are finished!\n"); 
}

//大儿子吃橘子 
void* Eldestson(void* arg)
{	
	int num=0;//用于记录大儿子吃了几个橘子 
	while(1)
	{  
        		sem_wait(&orange);//查看盘子里是否有橘子 
        		sem_wait(&mutex);//查看弟弟是否吃了上一个橘子 
		num++;
		printf("大儿子吃掉橘子!!!这是大儿子吃的第%d个橘子\n\n",num);
		sem_post(&mutex);//提醒弟弟吃下一个橘子 
		sem_post(&empty);//提醒父母盘子空了 
        		sleep(5); //休眠5毫秒
	}
}

//小儿子吃橘子 
void* Youngestson(void* arg)
{	
   	 int num=0;
	while(1)
	{   
        		sem_wait(&orange);//查看盘子里是否有橘子
        		sem_wait(&mutex);//查看哥哥是否吃了上一个橘子 
		num++;
		printf("小儿子吃掉橘子!!!这是小儿子吃的第%d个橘子\n\n",num);
		sem_post(&mutex);//提醒弟弟吃下一个橘子
		sem_post(&empty);//提醒父母盘子空了 
        		sleep(5);  //休眠5毫秒
	}
}

//女儿吃苹果 
void* Daughter(void* arg)
{	int num=0;
	while(1)
	{   
       		 sem_wait(&apple);//查看盘子里是否有苹果 
		num++;
		printf("女儿吃掉苹果!!!这是女儿吃的第%d个苹果\n\n",num);
		sem_post(&empty);//提醒父母盘子空了
        		sleep(5);  //休眠5毫秒
	}
}

int main()
{   
	pthread_t Fatherth,Motherth,Eldestsonth,Youngestsonth,Daughterth;//定义线程号 
	//初始化线程 
	sem_init(&empty,0,1);//初始值为1,盘子为空,用于父亲母亲互斥 
	sem_init(&orange,0,0);//初始值为0,盘子没有苹果
	sem_init(&apple,0,0);//初始值为0,盘子没有橘子
	sem_init(&mutex,0,1);//初始值为1,哥哥弟弟交互拿橘子
	int applenum,orangenum; //表示买的橘子和苹果个数 
	printf("请输入苹果,橘子个数(中间用逗号分隔):"); 
	scanf("%d,%d",&applenum,&orangenum);

	//创建线程
	pthread_create(&Fatherth, NULL, Father, (void*)applenum);
	pthread_create(&Motherth, NULL, Mother,(void*)orangenum);
	pthread_create(&Eldestsonth, NULL, Eldestson, NULL);
	pthread_create(&Youngestsonth, NULL, Youngestson, NULL);
	pthread_create(&Daughterth, NULL, Daughter, NULL);
	//主线程等待 
	pthread_join(Fatherth, NULL);
	pthread_join(Motherth, NULL);
	pthread_join(Eldestsonth, NULL);
	pthread_join(Youngestsonth, NULL);
	pthread_join(Daughterth, NULL);
	
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值