大家好,之前的很多文章中,我都提到了状态机,是因为平时用的很多,有时候也确实十分实用。
上述链接中汇总了有关QP状态机和有限状态机的一些精选文章,对此感兴趣的读者可以去了解一下。本文将总结一下状态机编程的优点。
提高 CPU 使用效率
我不得不说,每当我看到满篇都是 delay_ms() 的程序,就会头疼。动辄几十毫秒甚至更长的软件延时,实际上是对 CPU 资源的巨大浪费。宝贵的 CPU 时间都被浪费在无操作指令上。那种为了等待一个引脚电平变化或一个串口数据而让整个程序停滞的情况也让我非常纠结。如果这个事件永远不会发生,你是不是要等到天荒地老?这里我想说一下关于 CPU 的理解。
如果应用状态机编程思想,程序只需要使用全局变量记录当前的工作状态,然后就可以转而做其他的工作了。当然,在完成其他工作之后,还需要检查工作状态是否发生了变化。只要目标事件(如定时未到、引脚电平未变化、串口数据未接收完)还没有发生,工作状态就不会改变。程序就会一直重复着“查询-做其他事情-查询-做其他事情”的循环,这样 CPU 就不会闲置了。
这种处理方法的实质是在程序等待事件的过程中,间隔性地插入一些有意义的工作,以确保 CPU 不会一直无谓地等待。
逻辑完备性
逻辑完备性是状态机编程最大的优点。
不知道大家有没有用C语言写过计算器的小程序,我很早以前写过,写出来一测试,那个惨不忍睹啊!当我规规矩矩的输入算式的时候,程序可以得到正确的计算结果,但要是故意输入数字和运算符号的随意组合,程序总是得出莫名其妙的结果。
后来我试着思维模拟一下程序的工作过程,正确的算式思路清晰,流程顺畅,可要碰上了不规矩的式子,走着走着我就晕菜了,那么多的标志位,那么多的变量,变来变去,最后直接分析不下去了。
很久之后我认识了状态机,才恍然明白,当时的程序是有逻辑漏洞的。如果把这个计算器程序当做是一个反应式系统,那么一个数字或者运算符就可以看做一个事件,一个算式就是一组事件组合。对于一个逻辑完备的反应式系统,不管什么样的事件组合,系统都能正确处理事件,而且系统自身的工作状态也一直处在可知可控的状态中。反过来,如果一个系统的逻辑功能不完备,在某些特定事件组合的驱动下,系统就会进入一个不可知不可控的状态,与设计者的意图相悖。
状态机就能解决逻辑完备性的问题。
状态机是一种以系统状态为中心,以事件为变量的设计方法,它专注于各个状态的特点以及状态之间相互转换的关系。状态的转换恰恰是事件引起的,那么在研究某个具体状态的时候,我们自然而然地会考虑任何一个事件对这个状态有什么样的影响。这样,每一个状态中发生的每一个事件都会在我们的考虑之中,也就不会留下逻辑漏洞。
这样说也许大家会觉得太空洞,实践出真知,某天如果你真的要设计一个逻辑复杂的程序,会觉得状态机真香!
程序结构清晰
用状态机写出来的程序的结构是非常清晰的。
程序员最痛苦的事儿莫过于读别人写的代码。关于文档、注释的重要性以及如何去写。
如果代码不是很规范,而且手里还没有流程图,读代码会让人晕了又晕,只有顺着程序一遍又一遍的看,很多遍之后才能隐约地明白程序大体的工作过程。有流程图会好一点,但是如果程序比较大,流程图也不会画得多详细,很多细节上的过程还是要从代码中理解。
相比之下,用状态机写的程序要好很多,拿一张标准的UML状态转换图,再配上一些简明的文字说明,程序中的各个要素一览无余。程序中有哪些状态,会发生哪些事件,状态机如何响应,响应之后跳转到哪个状态,这些都十分明朗,甚至许多动作细节都能从状态转换图中找到。可以毫不夸张的说,有了UML状态转换图,程序流程图写都不用写。
以上就是良许教程网为各位朋友分享的Linu系统相关内容。想要了解更多Linux相关知识记得关注公众号“良许Linux”,或扫描下方二维码进行关注,更多干货等着你 !