Part-1 如何设计

        这次就直接分析程序如何设计的好了,从第四次作业开始,就和多线程打上了交道。第一次的多线程电梯,第二次的简单文件监控,第三次的简单出租车调度,每一次都得用心系统规划总体框架,假如一开始规划的好,实现思路并不算难,但是细节还是繁琐。

一、多线程电梯

        因为这次要求的是三部电梯,与之前的不同之处就在于如何分配,剩下的如何捎带就与之前的那次单线程捎带电梯一样了,主体的设计思路就在于如何调度。大概流程一目了然,就是每当一个请求进入之后,调度器都考虑是不是有电梯可以分配,如果有的话就分配,没有的话就等待;电梯呢,有请求就运动(如何运动与上一次相同),否则就等待。

         所以问题的关键就是如何调度。首先考虑分配请求的原理,对于每条请求,如果有电梯能够捎带它,就找那个运动量最少的电梯。否则,选择正在等待的运动量最少的电梯。再没有就跳过这条,去分配下一条。所以基于这个思路,设计出来的类图如下:

  

二、简单的文件监控程序

        依然先考虑设计思路。基于对指导书的理解,本人选择了每条请求一个线程的方式。而这就分为两类,一种是对文件的监控,另一种是对目录的监控。但思考一番过后发现,其实二者相差的并不是很多。

         得到了监控队列,那么就好说了。隔一段时间更新一次,再与上一次的做个对比,就能够得出哪些变了那些没变,哪些需要输出等等。由上表可知,不管对文件,还是目录而言,扫描的范围都是一个目录;对待该目录下所有文件的态度,是添加进监控队列;对待该目录下所有目录的态度,是递归思路,对子目录进行与父目录相同的措施。说明二者构建出来的监控队列是一样的,唯一不同的就是不同的响应机制。文件只关注某一个文件的变化,而目录关注所有文件变化而已。

        在线程选择上,实现每个IFTHEN请求一个线程,自己监控自己的,互不干扰,是普遍共识对吧;还有就是输入、输出,分别使用一个线程,所以设计类图如下,相较于多线程电梯清晰许多。

三、第一次多线程出租车

        出租车的运行思路并不是难点,而困难的在于时间,那么多线程想要做到实时还真是困难的一件事情,这也意味着可能分配完一单之后,过一会儿司机师傅才能反应过来,导致时序上出现差错。不过还是先聊聊程序框架。

        我这次设计思路和多线程电梯类似,就是由一个总调度器负责所有请求的分配问题,对于每条请求,都要找起点所在2*2的方格中是否有车辆,并且分配;出租车只关注自己是否被派了单,如果有单,就按照有单的方式运行,没有就按照空闲的方式运行。

        基于上述思路的设计类图如下:

 


Part-2 结果回顾

        第五次的电梯的度量图如下:

        Scheduler是上一次的用于继承的类,所以未作修改,上一次圈复杂度很高。而这次的新调度器是在之前的基础上直接进行删改,可以说会好一些。但是因为调度器线程里判断层次递进,深度过大,导致出现了层次爆红。

        这一次的作业很可惜,第一次多线程本来写的好好的,但是因为使用的是实际时间,再截止前才知道这个差1ms会被当做判罚依据,所以临时匆忙修改,改用虚假时间。但是因为改动不够,导致时间输出有问题,公测WA了5个,互测没有出现问题,找了对面1个半ERROR。

        第六次的文件监控的度量图如下:

        这次作业里最复杂的地方是通过对比前后两次Snapshot的差别,来发现有哪里改动过,以此分配给不同的Trigger,所以并列判断在所难免;而Recover的判断和执行又是最复杂的,所以判断的深度相应也很高。

        这次作业自己未被发现Bug,找了别人2个半ERROR。

        第七次的出租车调度的度量图如下:

        这一次相对来说写的较为均衡,各个类之间信息获取较为平等,但是由于需要输出的数据过多,所以储存了各种各样的信息在Request里面。并列最多的是Gui自带的draw方法,而调度器的Run方法又是由于判断过多导致深度很大。

        本次作业被找出两个ERROR,一个是因为输出信息太多了,导致其中某一项的明显错误没有发现:因为要求输出两遍,我就简单的把两条路径分别处理,使得对于乘客所在的地点,到达了两次,又休息1000ms,所以结果看上去就是休息了1200ms;另一个是大概是因为分配的速度问题,导致窗口结束时间和真正接单时间不一致,窗口结束地点并不是出租车反应过来的地点。找了对面一个ERROR。

        找自己BUG和别人BUG首先要克服的就是面对大量信息的浮躁心理。对于出租车或者以后面临的系统工程问题,对错误日志的认真阅读是必要的。如何在面对大量琐碎信息时沉住气,一点点分析结果是最重要的。这次作业因为OS考试还有临近五一,导致投入的心思并不多,后面三次继续努力,摆正心态通过大量阅读学习别人的优点,找寻自己的不足。


Part-3 结语

        多线程的程序其实思路上并不复杂,就是各种细节与更好实现要更困难,毕竟保证正确性的同时,让自己的代码更简洁美观,而且成系统才是自己更想要Get到的。

        突然发现,写博客的帮助其实挺大的。自己写完的作业基本上是不会再去看了,但是通过写博客,又重新把自己当时实现的思路,还有码代码的流程回忆了一遍,并且认认真真分析分析自己哪里有不足,还是蛮好的。

        上一次写博客的时候,觉得Metric没啥用,因为感觉很多地方不可避免的要很复杂。但是这一次通过它发现自己三次作业的Run方法都是深度过大,不禁回想起纪导课上说过Run方法里的代码越少越好,当时不以为意,觉得自己好像放的不是很多,总要有人告诉自己有问题的时候才能发现。所以有这么一个辅助工具还是挺不错的,争取用后相对轻松一点的后半学期扳扳自己的代码风格和实现问题的方法吧。

posted on 2018-05-02 17:33  MyLife'  阅读(143)  评论(0编辑  收藏  举报