网易公开课,多线程,冰淇淋问题,VC2010控制台程序编译通过:
/* testVC.cpp : 冰激凌店问题。
**问题描述:有N个客户到冰淇淋店中买[1-n]个甜筒,店员接到订单后开始做甜筒,
**每一个甜筒都需经理检验,合格后才能交付顾客。顾客得到所需数量甜筒后到收银员处结账。
*/
**问题描述:有N个客户到冰淇淋店中买[1-n]个甜筒,店员接到订单后开始做甜筒,
**每一个甜筒都需经理检验,合格后才能交付顾客。顾客得到所需数量甜筒后到收银员处结账。
*/
#include "stdafx.h"
#include <time.h>
#include <time.h>
//客户数量
#define NUMCUSTUMS 5
//甜筒最大购买数
#define NUMCONES 10
typedef struct Customers {
int id; //客户ID
int numcones; //购买甜筒数
}CUSTOMER; //客户信息
#define NUMCUSTUMS 5
//甜筒最大购买数
#define NUMCONES 10
typedef struct Customers {
int id; //客户ID
int numcones; //购买甜筒数
}CUSTOMER; //客户信息
struct Inspection {
boolean passed; //检验结果
HANDLE hRequested; //请求检验
HANDLE hFinished; //检验完成
HANDLE hinspectlock; //检验室空闲锁
}inspection; //检验信号量组
struct Line {
int number; //排队号
HANDLE hCustomers[NUMCUSTUMS]; //客户排队状态
HANDLE hRequested; //请求结账
HANDLE hnumblock; //取号锁
CUSTOMER customers[NUMCUSTUMS]; //待结账客户信息
}line; //结账信号量组
boolean passed; //检验结果
HANDLE hRequested; //请求检验
HANDLE hFinished; //检验完成
HANDLE hinspectlock; //检验室空闲锁
}inspection; //检验信号量组
struct Line {
int number; //排队号
HANDLE hCustomers[NUMCUSTUMS]; //客户排队状态
HANDLE hRequested; //请求结账
HANDLE hnumblock; //取号锁
CUSTOMER customers[NUMCUSTUMS]; //待结账客户信息
}line; //结账信号量组
HANDLE hAlldone; //完成客户服务信号量
void InitSemaphore(); //初始化信号量
DWORD _stdcall Manager(LPVOID lpParameter);
DWORD _stdcall Clerk(LPVOID lpParameter);
DWORD _stdcall Customer(LPVOID lpParameter);
DWORD _stdcall Cashier(LPVOID lpParameter);
void InitSemaphore(); //初始化信号量
DWORD _stdcall Manager(LPVOID lpParameter);
DWORD _stdcall Clerk(LPVOID lpParameter);
DWORD _stdcall Customer(LPVOID lpParameter);
DWORD _stdcall Cashier(LPVOID lpParameter);
int main(int argc, char* argv[])
{
int totalcones = 0; //甜筒总数
CUSTOMER customers[NUMCUSTUMS]; //客户信息
//初始化信号量
InitSemaphore();
SYSTEMTIME currentTime;
GetSystemTime(¤tTime);
srand(currentTime.wMilliseconds);
{
int totalcones = 0; //甜筒总数
CUSTOMER customers[NUMCUSTUMS]; //客户信息
//初始化信号量
InitSemaphore();
SYSTEMTIME currentTime;
GetSystemTime(¤tTime);
srand(currentTime.wMilliseconds);
for(int i=0;i<NUMCUSTUMS;i++)
{
customers[i].id = i;
customers[i].numcones = rand()%NUMCONES + 1; //客户购买甜筒数
CreateThread(NULL,1,Customer,&customers[i], 0, NULL); //创建客户线程
totalcones += customers[i].numcones;
printf("客户 %d 购买 %d 个甜筒\n",i,customers[i].numcones);
}
printf("甜筒总数是 %d\n",totalcones);
CreateThread(NULL,1,Manager,&totalcones, 0, NULL); //创建经理线程
CreateThread(NULL,0,Cashier,NULL, 0, NULL); //创建收银员线程
for(int i=0;i<NUMCUSTUMS;i++) //等待所有客户取得甜筒结账离店
{
WaitForSingleObject(hAlldone, INFINITE);
}
printf("当天服务完毕,营业额为%d个甜筒\n",totalcones);
return 0;
}
/*Manager,检验Clerk送来的甜筒
**参数为检验数量
*/
DWORD _stdcall Manager(LPVOID lpParameter)
{
int totalcones = *(int *)lpParameter;
int numInspected = 0; //检验数量
int numAccepted = 0; //质量通过数量
while(numAccepted < totalcones) {
WaitForSingleObject(inspection.hRequested, INFINITE); //等待店员申请质量检验
Sleep(100); //模拟检验过程
numInspected ++;
inspection.passed = rand()%2; //检验结果,随机
if(inspection.passed)
{
numAccepted ++;
}
ReleaseSemaphore(inspection.hFinished,1,NULL); //完成一个检验
}
printf("经理检验了 %d 个甜筒, %d 个合格\n",numInspected,numAccepted);
return 0;
}
/*Clerk,生产一个合格甜筒,每生产一个就送Manager检验
**参数:交付甜筒信号量,完成则信号量++
*/
DWORD _stdcall Clerk(LPVOID lpParameter)
{
boolean passed = false;
HANDLE hClerkdone = (HANDLE)lpParameter;
while(!passed)
{
Sleep(100); //模拟做甜筒
WaitForSingleObject(inspection.hinspectlock, INFINITE);//等待进入Manager办公室
ReleaseSemaphore(inspection.hRequested,1,NULL); //申请Manager检验
WaitForSingleObject(inspection.hFinished, INFINITE); //等待检验完成
passed = inspection.passed; //取得检验结果
ReleaseSemaphore(inspection.hinspectlock,1,NULL); //离开Manager办公室
}
ReleaseSemaphore(hClerkdone,1,NULL); //当前甜筒交付给客户
return 0;
}
/*Customer,购买甜筒,并去结账
**参数为该客户信息
*/
DWORD _stdcall Customer(LPVOID lpParameter)
{
CUSTOMER *pcustomer = (CUSTOMER *)lpParameter;
HANDLE hClerkdone = CreateSemaphore(NULL, 0, pcustomer->numcones, NULL); //交付甜筒信号量
WaitForSingleObject(inspection.hRequested, INFINITE); //等待店员申请质量检验
Sleep(100); //模拟检验过程
numInspected ++;
inspection.passed = rand()%2; //检验结果,随机
if(inspection.passed)
{
numAccepted ++;
}
ReleaseSemaphore(inspection.hFinished,1,NULL); //完成一个检验
}
printf("经理检验了 %d 个甜筒, %d 个合格\n",numInspected,numAccepted);
return 0;
}
/*Clerk,生产一个合格甜筒,每生产一个就送Manager检验
**参数:交付甜筒信号量,完成则信号量++
*/
DWORD _stdcall Clerk(LPVOID lpParameter)
{
boolean passed = false;
HANDLE hClerkdone = (HANDLE)lpParameter;
while(!passed)
{
Sleep(100); //模拟做甜筒
WaitForSingleObject(inspection.hinspectlock, INFINITE);//等待进入Manager办公室
ReleaseSemaphore(inspection.hRequested,1,NULL); //申请Manager检验
WaitForSingleObject(inspection.hFinished, INFINITE); //等待检验完成
passed = inspection.passed; //取得检验结果
ReleaseSemaphore(inspection.hinspectlock,1,NULL); //离开Manager办公室
}
ReleaseSemaphore(hClerkdone,1,NULL); //当前甜筒交付给客户
return 0;
}
/*Customer,购买甜筒,并去结账
**参数为该客户信息
*/
DWORD _stdcall Customer(LPVOID lpParameter)
{
CUSTOMER *pcustomer = (CUSTOMER *)lpParameter;
HANDLE hClerkdone = CreateSemaphore(NULL, 0, pcustomer->numcones, NULL); //交付甜筒信号量
for(int i=0;i<pcustomer->numcones;i++)
{
CreateThread(NULL,1,Clerk,hClerkdone, 0, NULL); //需要店员做numcones个甜筒
}
for(int i=0;i<pcustomer->numcones;i++)
{
WaitForSingleObject(hClerkdone, INFINITE); //等待取得所需甜筒
}
printf("客户%d ,已拿到 %d 个甜筒,开始排队结账\n",pcustomer->id,pcustomer->numcones);
//开始排队结账
WaitForSingleObject(line.hnumblock, INFINITE); //取排队号码
int place = line.number++;
ReleaseSemaphore(line.hnumblock,1,NULL);
line.customers[place].id = pcustomer->id; //保存客户信息
line.customers[place].numcones = pcustomer->numcones;
ReleaseSemaphore(line.hRequested,1,NULL); //申请结账
WaitForSingleObject(line.hCustomers[place], INFINITE); //等待收银员结账
{
CreateThread(NULL,1,Clerk,hClerkdone, 0, NULL); //需要店员做numcones个甜筒
}
for(int i=0;i<pcustomer->numcones;i++)
{
WaitForSingleObject(hClerkdone, INFINITE); //等待取得所需甜筒
}
printf("客户%d ,已拿到 %d 个甜筒,开始排队结账\n",pcustomer->id,pcustomer->numcones);
//开始排队结账
WaitForSingleObject(line.hnumblock, INFINITE); //取排队号码
int place = line.number++;
ReleaseSemaphore(line.hnumblock,1,NULL);
line.customers[place].id = pcustomer->id; //保存客户信息
line.customers[place].numcones = pcustomer->numcones;
ReleaseSemaphore(line.hRequested,1,NULL); //申请结账
WaitForSingleObject(line.hCustomers[place], INFINITE); //等待收银员结账
printf("客户%d ,结账编号 %d,服务完毕\n",pcustomer->id,place);
ReleaseSemaphore(hAlldone,1,NULL); //一个客户服务完毕,完成量hAlldone++
return 0;
}
//Cashier,结账
DWORD _stdcall Cashier(LPVOID lpParameter)
{
for(int i=0;i<NUMCUSTUMS;i++)
{
WaitForSingleObject(line.hRequested, INFINITE); //等待结账请求
Sleep(100); //模拟结账
printf("客户%d,结账编号%d,购买了%d个甜筒,已结账\n",line.customers[i].id,i,line.customers[i].numcones);
ReleaseSemaphore(line.hCustomers[i],1,NULL); //第i个客户结账完成
}
return 0;
}
//初始化信号量
void InitSemaphore()
{
inspection.passed = false; //是否检验合格
inspection.hRequested = CreateSemaphore(NULL, 0, 1, NULL); //请求检验信号量,初始为0
inspection.hFinished = CreateSemaphore(NULL, 0, 1, NULL); //检验完成信号量,初始为0
inspection.hinspectlock = CreateSemaphore(NULL, 1, 1, NULL); //检验室锁信号量,初始为1
ReleaseSemaphore(hAlldone,1,NULL); //一个客户服务完毕,完成量hAlldone++
return 0;
}
//Cashier,结账
DWORD _stdcall Cashier(LPVOID lpParameter)
{
for(int i=0;i<NUMCUSTUMS;i++)
{
WaitForSingleObject(line.hRequested, INFINITE); //等待结账请求
Sleep(100); //模拟结账
printf("客户%d,结账编号%d,购买了%d个甜筒,已结账\n",line.customers[i].id,i,line.customers[i].numcones);
ReleaseSemaphore(line.hCustomers[i],1,NULL); //第i个客户结账完成
}
return 0;
}
//初始化信号量
void InitSemaphore()
{
inspection.passed = false; //是否检验合格
inspection.hRequested = CreateSemaphore(NULL, 0, 1, NULL); //请求检验信号量,初始为0
inspection.hFinished = CreateSemaphore(NULL, 0, 1, NULL); //检验完成信号量,初始为0
inspection.hinspectlock = CreateSemaphore(NULL, 1, 1, NULL); //检验室锁信号量,初始为1
line.number = 0; //结账排队号
line.hnumblock = CreateSemaphore(NULL, 1, 1, NULL); //排队取号锁,初始为1
line.hRequested = CreateSemaphore(NULL, 0, 1, NULL); //排队等待结账信号,初始为0
for(int i=0;i<NUMCUSTUMS;i++)
{
line.hCustomers[i] = CreateSemaphore(NULL, 0, 1, NULL); //已结账信号量,初始为0
}
hAlldone = CreateSemaphore(NULL, 0, NUMCUSTUMS, NULL); //所有客户服务完毕信号,初始为0
}
line.hnumblock = CreateSemaphore(NULL, 1, 1, NULL); //排队取号锁,初始为1
line.hRequested = CreateSemaphore(NULL, 0, 1, NULL); //排队等待结账信号,初始为0
for(int i=0;i<NUMCUSTUMS;i++)
{
line.hCustomers[i] = CreateSemaphore(NULL, 0, 1, NULL); //已结账信号量,初始为0
}
hAlldone = CreateSemaphore(NULL, 0, NUMCUSTUMS, NULL); //所有客户服务完毕信号,初始为0
}