C-多线程,冰淇淋问题

来源:互联网 发布:淘宝开店卖什么好起步 编辑:程序博客网 时间:2024/04/28 05:59

网易公开课,多线程,冰淇淋问题,VC2010控制台程序编译通过:

/* testVC.cpp : 冰激凌店问题。
**问题描述:有N个客户到冰淇淋店中买[1-n]个甜筒,店员接到订单后开始做甜筒,
**每一个甜筒都需经理检验,合格后才能交付顾客。顾客得到所需数量甜筒后到收银员处结账。
*/
#include "stdafx.h"
#include <time.h>
//客户数量
#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; //结账信号量组
HANDLE hAlldone; //完成客户服务信号量
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(&currentTime);
 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); //交付甜筒信号量
 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); //等待收银员结账
 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
 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
}

原创粉丝点击