操作系统实验—进程同步(吃水果问题)

  • Post author:
  • Post category:其他




题目

桌上有一空盘,最多允许存放一只水果。爸爸可向盘中放一个苹果或放一个桔子,儿子专等吃盘中的桔子,女儿专等吃苹果。

试用P、V操作实现爸爸、儿子、女儿三个并发进程的同步。

提示:设置一个信号量表示可否向盘中放水果,一个信号量表示可否取桔子,一个信号量表示可否取苹果。

实验目的:

深入掌握进程、线程同步机制——信号量机制的原理与应用;

掌握Windows编程中信号量机制的使用方法;

掌握Windows下线程的控制方法;

可进行简单的信号量应用编程。



解题思路

下面展示一些

内联代码片

从这个题意可以得出,这个实验一共有3个进程,
分别是父亲,儿子,女儿。
且要设置3个信号量,
S:表示是否可以向盘子防水果  初值为1 表示盘子为空
S0:表示盘子中放的是桔子 初值为0  表示盘子内不是桔子
S1:表示盘子中放的是苹果 初值为0 表示盘子内不是苹果
// 进行P,V操作(P,V操作为原子操作不可被打断)
//父亲
father()
{ while(1){
  P(S);//申请盘子的使用权
  将水果放入盘中
  if(是桔子){
  V(S0);//释放是桔子的信号量,S0+1)
  }
  else{
  V(S1);//释放是苹果的信号量,S1+1)
  }
}
}

//儿子
son() 
{while(1){
  p(S0);//等待盘子中是桔子的信号
  取桔子;
  V(S);释放盘子的使用权
  吃桔子;
}
}

//女儿
daughter() 
{while(1){
  p(S1);//等待盘子中是苹果的信号
  取苹果;
  V(S);释放盘子的使用权
  吃苹果;
}
}



源码实现

#include <windows.h>
#include <iostream>
#include<stdio.h>

bool g_continue = true; //控制程序结束
HANDLE g_hS; //当盘子为空时的线程 
HANDLE g_hS0; //当盘子中放的是桔子线程 
HANDLE g_hS1; //当盘子中放的是苹果线程 
DWORD WINAPI father(LPVOID); //定义父亲线程
DWORD WINAPI son(LPVOID); //定义儿子线程
DWORD WINAPI daughter(LPVOID);//定义女儿线程
int main()  
{  
 //创建各个互斥与资源信号量  
 g_hS = CreateSemaphore(NULL,1,1,NULL);  //盘子中是否有水果 
 g_hS0 = CreateSemaphore(NULL,0,1,NULL);  //盘子中的水果为桔子 
 g_hS1 = CreateSemaphore(NULL,0,1,NULL);  //盘子中的水果为苹果 

//其中第2和3个参数为信号量的初始值和最大值

 const unsigned short father_COUNT = 0; //声明父亲
 const unsigned short son_COUNT = 0; //声明儿子
 const unsigned short daughter_COUNT = 0;//声明女儿
 
 //总的线程数 
 const unsigned short THREADS_COUNT = father_COUNT+son_COUNT+daughter_COUNT ;  
 HANDLE hThreads[THREADS_COUNT]; //各线程的handle  
 DWORD fatherID[father_COUNT]; //父亲线程的标识符
 DWORD sonID[son_COUNT]; //儿子线程的标识符  
 DWORD daughterID[daughter_COUNT]; //女儿线程的标识符
 
//创建父亲进程

 hThreads[0]=CreateThread(NULL,0,father,NULL,0,&fatherID[0]);  
  if (hThreads[0]==NULL) return -1;  
 
//创建儿子进程
  
 hThreads[1]=CreateThread(NULL,0,son,NULL,0,&sonID[0]);  
  if (hThreads[1]==NULL) return -1;  
 
//创建女儿进程
 
 hThreads[2]=CreateThread(NULL,0,daughter,NULL,0,&daughterID[0]);  
  if (hThreads[2]==NULL) return -1;  


 while(g_continue){  
  if(getchar()){ //按回车后终止程序运行  
	  g_continue = false;  
  }  
 }  

 return 0;  
}  
//父亲放水果的操作,输出  

void eat()  
{  
 std::cerr << "儿子吃桔子" << std::endl;  
}  

 
void eat1()  
{  
 std::cerr << "女儿吃苹果" << std::endl;  
}  

//父亲进程  
DWORD WINAPI father(LPVOID lpPara)  
{  
 while(g_continue){  
  WaitForSingleObject(g_hS,INFINITE);   
  
  int juzhi=rand()%2; //设置了一个随机数,来模拟父亲放的是什么水果 
  Sleep(1500);//方便观察实验结果
  if(juzhi==1){
  	  printf("父亲放入了一个桔子\n");
  	  Sleep(1000);
      ReleaseSemaphore(g_hS0,1,NULL); 
  }
  else{
  	printf("父亲放入了一个苹果\n"); 
  	Sleep(1000);
	   ReleaseSemaphore(g_hS1,1,NULL); 
 }
 }  
 return 0;  
}  

//儿子进程 
DWORD WINAPI son(LPVOID lpPara)  
{  
 while(g_continue){  
  WaitForSingleObject(g_hS0,INFINITE); 
   eat(); 
   Sleep(1500); 
  ReleaseSemaphore(g_hS,1,NULL);   
 }  
 return 0;  
}    

//女儿进程 
DWORD WINAPI daughter(LPVOID lpPara)  
{  
 while(g_continue){  
  WaitForSingleObject(g_hS1,INFINITE);    
  eat1(); 
  Sleep(1500); 
  ReleaseSemaphore(g_hS,1,NULL); 
 }  
 return 0;  
}    



实验结果

在这里插入图片描述

Thanks



版权声明:本文为m0_56145255原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。