电梯多线程调度----需求分析及详细设计
电梯多线程调度----需求分析及详细设计
小组成员:刘铸辉,何晓楠
1.进程管理
首先,做一个项目无论大小,时间规划和进程管理是最根本的,下面是我们的进程管理。
执行计划 | |||||||
任务名称 | 开始日期 | 结束日期 | 实际用时 | 人员 | 备注 | ||
计划 | 实际 | 计划 | 实际 | ||||
需求分析文档设计 |
3月5日 星期三 |
3月5日 星期三 |
3月7日 星期五 |
3月7日 星期五 |
2天 |
刘铸辉 何晓楠 |
|
详细设计文档设计 |
3月7日 星期五 |
3月7日 星期五 |
3月9日 星期日 |
3月9日 星期日 |
2天 |
刘铸辉 何晓楠 |
|
项目功能的实现 |
3月9日 星期日 |
3月9日 星期日 |
3月13日 星期四 |
待定 | 待定 | 待定 | |
测试用例文档 |
3月13日 星期四 |
待定 |
3月15日 星期六 |
待定 | 待定 | 待定 | |
项目结项报告 |
3月16日 星期日 |
待定 |
3月17日 星期一 |
待定 | 待定 | 待定 |
该项目的任务布置时间是3月3日,由于有段时间没有拿C#做过小项目开发了,所以我和小楠先用三天时间通过看教学视频和查资料做了一个扫雷的小项目,项目不大,但是我们使用严格的项目开发来写的,电梯调度的项目我们也用项目开发的步骤来写。并且用这三天的时间强化了C#的语法和多线程的操作。
3月5日,我们开始着手项目的设计和构思。
2.需求分析
2.1电梯说明
1. 管理者需求描述
- 实现项目的可管理性,能够监控电梯的安全。
- 实现项目的及时性,当出现问题时候,可以及时的采取施,达到保证人员安全的效果。
- 实现项目的可调控性,能够使用户在不同环境中使用项目,并且能够达到相同的效果。
2. 用户(内)需求描述
- 正常的开关门
- 可以去任何一层楼层
- 若出现紧急情况时候,可以停止电梯运作,并发送警报给管理人员
- 查看电梯所在当前楼层
- 知道电梯是否已经满载
3. 用户(外)需求描述
- 查看电梯所在楼层
- 请求电梯过来,并打开
- 得知电梯是否能打开
4. 电梯调度需求描述
1.电梯内部视图1-20为相应的楼层,按下变为红色即可响应楼层
2.电梯到达相应楼层后会按钮会变色,表示门被打开
3.开关门按钮,只有在电梯停下来,或者电梯正在开门时(延长开门时间)响应,关门键只有在开门以后,按下可以立刻关门,并继续上下移动。
4.外部的38个按钮为4部电梯共享。
2.2实地考察
1·我们的调查对象是春晖楼(11层),时间:3月11日中午13:10;
2.电梯开关门时间是2.65s,为了编程方便取2s;
3.从1层到11层,无其他乘客乘坐的情况下,有3个数据28.65s,29.21s,29.01s,为了编程方便取29s,则平均每层通过的时间是3s;
4.调查了电梯如何多线程调度。两部电梯一个在9层,一个在6层停下,我俩去7层请求向上走,发现6层的那个电梯过来了,那么一定是调用了最短路径算法,7层离6层最近。
5.得出了两个结论。
1.电梯优先考虑内部按钮,对于外部请求,只有顺路的情况下,才会有响应,否则一律不响应。
2.当两部电梯都不工作的时候,当有用户发送上楼或者下楼的请求,会调用最短路径算法将最近的电梯调度过来。
3.详细设计
3.1重要参数及变量
3.1.1Elevator类
boolean arrive[40]; //用于记录电梯内部的按钮,也就是电梯需要到达的楼层
arrive是用于存放电梯请求的信息。0~18表示1~19楼的一个向上走的请求,21~38表示20楼到2楼向下走的请求。
arrive[19]与arrive[39]没有使用是因为在20楼不存在向上的请求以及在1楼不存在向下的请求之所以不给arrive设置20个,而设置40个的原因是因为,电梯分上下行走,如果5楼有2个孩纸,一个按往下行走,一个按往上行走,那么,应该响应的是不同的按钮。
3.1.2将电梯的状态分为5个状态
int state //电梯的状态
(1)0 静止 (等待状态)
(2)1 向上走(去接一个向上走的请求) 比如 电梯在1楼; 3楼按下一个往上走的请求
(3)2 向上走(去接一个向下走的请求) 比如 电梯在1楼; 3楼按下一个往下走的请求
(4)-1 向下走(去接一个向下走的请求) 比如 电梯在5楼; 3楼按下一个向下走的请求
(5)-2 向下走 (去接一个向上走的请求) 比如 电梯在5楼; 3楼按下一个向上走的请求
int willArrive //电梯沿着这个方向运行最终的楼层
int floor //目前电梯在哪一个楼层
3.1.3RequireButton类
bool require[40] //电梯外部的按钮请求状态
3.2实现思想
3.2.1先从简单的一部电梯的内部按钮开始
(1)只有一部电梯时,电梯内部的按钮必须优先实现,不考虑外部按钮。在run方法中,每次调用upOrDown(内部调度核心函数)函数。
内部调度核心函数upOrDown函数会根据上一步的电梯状态state按照不同的顺序将电梯要到达的各个楼层arrive数组扫描一遍,并将返回值返回给新的电梯状态state。
(2)1.当state=1或者state=2时,内部调度核心函数upOrDown函数会从20楼扫描到当前电梯所在层floor,一旦遇到高层向下的请求,修改willArrive(电梯沿着这个方向运行最终的楼层),并且返回新的电梯状态state,之所以从20楼开始扫描是因为电梯目前状态向上,willArrive为一个需要到达的最高处需求
2.当state=-1和state=-2时,相同。
3.当state=0时,如果电梯所在楼层有开门响应这时候执行开门操作。
否则,将电梯要到达的各个楼层arrive[i]扫描一遍,一旦发现有一个楼层需要请求,立刻修改这个方向的最终到达楼层willArrive,并返回新的电梯状态。
(3)如果电梯内部没有请求了,检查是否有外部按钮被响应,如果有的话,需要修改电梯需要到达的楼层arrive函数,之后可以在下一次调用upOrDown函数中在修改后的电梯需要到达的楼层arrive函数中改变电梯状态。
(4)对于返回的新的电梯状态state
1.如果返回值为1或者2执行电梯上楼(upFloor函数);
2.如果返回值为-1或者-2,执行电梯下楼(downFloor函数);
(5)电梯上楼upFloor函数:
1.执行电梯上楼动画,在上完一楼以后,将floor++,并且判断电梯要到达的楼层和外部响应的楼层是否为同一层,如果是则表示该楼需要开门,则停止电梯,进行开门。之后返回启动电梯(run函数),再次调用调度核心函数(upOrDown函数)查看电梯下一步操作。否则无需开门,直接返回到run函数。
2.在这种情况下会响应向下的按钮。
当state==2(电梯本来就是想上接向下的乘客),并且同楼层外面的人只按下了向下的按钮(否则会先相应想上的按钮),并且电梯到达了电梯需要到达的最高楼层,则响应向下的按钮。
电梯下楼downFloor函数与upFloor类似。
3.2.2关于电梯内部按钮按下的楼层与arrive数组的响应
1.当按下的楼层>floor(电梯目前所在的楼层),则标记该楼为上楼的请求
2.当按下的楼层<floor,则标记该楼为下楼请求
3.当按下的楼层=floor,电梯处于开门状态,并延长开门时间
3.2.3响应仅一部电梯时的外部按钮
1.响应外部按钮只有在电梯静止状态下响应,除非是电梯顺路的情况,顺路的情况在upFloor和downFloor函数中已经解决。
2.剩下state=0的情况,在upOrDown函数中,首先搜索了电梯需要到达的楼层arrive数组,如果全为false,表示电梯内部没有需要到达的楼层,这样在检查是否有外部按钮被响应中,将外部请求赋值给电梯需要到达的楼层的数组。(额,感觉不是很对,暂时只能想到这了,看来多线程还是太懂,求大神帮助。。)
3.2.4响应多部电梯(search函数,调度4部电梯管理外部按钮)
(1)4部电梯是4个线程,线程之间相互工作,互不干涉。因此,内部原理完全相同,要在创建的时候多创建4个Elevator类即可。
(2)唯一不同之处是外部按钮。当有用户请求外部按钮的时候,调度一个最近的电梯过去有一些区别。这里,我们准备对于一个外部响应的电梯,在所有的静止电梯中,找到一个线路最短的电梯分配过去。也就完成了一部电梯到多部电梯的过度,也完成了4部电梯的调度工作。
我和小楠折腾了好几天才刚刚把需求分析写完,路还长着呢。感觉这个项目上,资源分配和进程调度的确是个难点,很多地方感觉思路还算清晰,只是有些地方可能也不太对,只能在编写功能模块的时候再发现了,希望大神们能给我们指点指点,谢谢了。