題目
桌上有一空盤,最多允許存放一只水果,爸爸可向盤中放一個蘋果或放一個桔子,兒子專等吃盤中的桔子,女兒專等吃蘋果,
試用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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/274498.html
標籤:其他
上一篇:H264碼流分析和打包RTP程序
下一篇:Signal Tap抓取波形
