C-多线程,冰淇淋问题
网易公开课,多线程,冰淇淋问题,VC2010控制台程序编译通过:
**问题描述:有N个客户到冰淇淋店中买[1-n]个甜筒,店员接到订单后开始做甜筒,
**每一个甜筒都需经理检验,合格后才能交付顾客。顾客得到所需数量甜筒后到收银员处结账。
*/
#include <time.h>
#define NUMCUSTUMS 5
//甜筒最大购买数
#define NUMCONES 10
typedef struct Customers {
int id; //客户ID
int numcones; //购买甜筒数
}CUSTOMER; //客户信息
boolean passed; //检验结果
HANDLE hRequested; //请求检验
HANDLE hFinished; //检验完成
HANDLE hinspectlock; //检验室空闲锁
}inspection; //检验信号量组
struct Line {
int number; //排队号
HANDLE hCustomers[NUMCUSTUMS]; //客户排队状态
HANDLE hRequested; //请求结账
HANDLE hnumblock; //取号锁
CUSTOMER customers[NUMCUSTUMS]; //待结账客户信息
}line; //结账信号量组
void InitSemaphore(); //初始化信号量
DWORD _stdcall Manager(LPVOID lpParameter);
DWORD _stdcall Clerk(LPVOID lpParameter);
DWORD _stdcall Customer(LPVOID lpParameter);
DWORD _stdcall Cashier(LPVOID lpParameter);
{
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; //质量通过数量
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); //交付甜筒信号量
{
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); //等待收银员结账
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.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
}
C-多线程,冰淇淋问题相关推荐
- Java SE - 10 - 多线程
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1. 线程的概述 2.多线程的创建与使用 2.1 方式一:继承的方式开启线程 2.2 方式二:实现Runnable接口方式开 ...
- 第十章_多线程(2)_线程池原子性并发工具类
目录 一.线程池 1 - 线程状态 2 - 线程池 3 - Executors线程池 二.Volatile 三.原子性 四.并发工具类 1 - 并发工具类-Hashtable 2 - 并发工具类-Co ...
- Java学习之路-day23 多线程02
Java多线程 每日一句 1.线程池 1.1 线程状态介绍 1.2 线程池-基本原理 1.3 线程池-Executors默认线程池 1.4 线程池-Executors创建指定上限的线程池 1.5 线程 ...
- Java 多线程概述
多线程技术概述 1.线程与进程 进程:内存中运行的应用程序,每个进程都拥有一个独立的内存空间. 线程:是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换.并发执行,一个进程最少有一个线程, ...
- Java 多线程的基本方式
Java 多线程的基本方式 基础实现两种方式: 通过实现Callable 接口方式(可得到返回值):
- RPC 笔记(08)— socket 通信(多进程多线程服务器)
在上一节中如果并行的客户端连接数超过了默认开启进程的数量,那么后来的客户端请求将会阻塞,为了不阻塞新的客户端,我们可以将进程的单线程改成多线程即可. 服务端代码: import json impo ...
- Python 多线程总结(2)— 线程锁、线程池、线程数量、互斥锁、死锁、线程同步
主要介绍使用 threading 模块创建线程的 3 种方式,分别为: 创建 Thread 实例函数 创建 Thread 实例可调用的类对象 使用 Thread 派生子类的方式 多线程是提高效率的一种 ...
- Python 多线程总结(1)- thread 模块
thread 模块 1. 单线程 首先看下单线程程序运行的例子,如下所示, import timedef loop0():print 'start loop0 begin', time.ctime() ...
- Python多线程调试
有时候程序是多线程的,调试的时候可能跑到别的线程了. 这个时候把thread.start变成threa.run就好了,就会执行完当前线程再执行下一个. for thread in threads:th ...
最新文章
- autowired java配置_Spring自动注解标签@Autowired不能注入xml配置的bean吗?
- python中fork创建新的进程
- Linux操作系统下三种配置环境变量的方法(linux下几种profile执行顺序)
- html仿苹果浏览器,完美仿iPhone风格主题 领航浏览器体验
- Thread打印值的含义
- 《诗经》诗无邪 —— 雅篇
- LeetCode:208. 实现 Trie (前缀树)
- 谈谈我心目中理想的牛人
- 佛说剖腹产的孩子_选择好的剖腹产时间会改变孩子的命运吗?
- MATLAB插值函数_akala啦_新浪博客
- Elastic官方网络研讨会视频列表
- linux watchdog超时时间,S3C2440看门狗定时器(Watchdog)
- 躲猫猫正式上线“Peek-a-Boo”就是“躲猫猫”
- 《简单的逻辑学》阅读笔记(思维导图)
- GridView指定列求和
- Java获取今天 开始和结束时间
- 管理跨国虚拟团队的技巧
- 大型B2C网站如何做好EDM营销
- BlackBerry 软件全球现已部署超过2.15亿辆汽车
- 第五章. 可视化数据分析图表—图表的常用设置1
热门文章
- 常用VK键盘值和解释
- 中国供应平台API,item_search - 按关键字搜索china商品
- Centos7 下 安装 Redis6.0.8
- 微信小程序图片预览保存发送给朋友previewImage
- html开始就执行某函数,立即执行函数.html
- 【云办公】在“我的电脑”中添加网盘,实现云办公
- Delphi 读取文本文件的两种方式
- android如何获得歌曲的路径,android通过MP3路径获取MP3的album
- CTS2018+1没去记APIO2018+1游记
- 对比JDBC,用MyBatis的好处及常见问题