Raw-OS源码分析之fsm(有限状态机)

来源:互联网 发布:除了程序员还有能 编辑:程序博客网 时间:2024/06/05 14:12

        分析的内核版本截止到2014-04-15,基于1.05正式版,blogs会及时跟进最新版本的内核开发进度,若源码注释出现”???”字样,则是未深究理解部分。

        Raw-OS官方网站:http://www.raw-os.org/

        Raw-OS托管地址:https://github.com/jorya/raw-os/

 

        这节来说说fsm(有限状态机)编程这点破事~

        所谓有限状态机,就是给活动对象定义有限个状态,然后活动对象不断地在规定的状态内转换,然后执行状态内的具体活动内容~

 

        一开始我们讲得不要太复杂了~还是上节“屌丝程序员的”例子,这节我们把这个例子抽象成fsm(有限状态机),在适当时候我们用Raw-OS的事件触发和fsm(有限状态机)的机制用代码来实现~本屌规划得还是可以滴~

 

一、状态抽象

        记住,还是上一节的例子“屌丝程序员的一天”

 


 

        实际上来说,本屌是一个程序员,那么描述我一天的工作内容就是~

        分内工作是码代码;然后有事没事调戏一下项目管理组的文员;再然后时不时老大会找我抽会烟,吐槽工资低;再不然就是工作没做好,被领导训话,等等······等等······

 

        那么就可以根据实际内容来抽象了~调戏文员一个;码代码一个;走一个一个,然后就是等等······等等······,把你遇到的都可以抽象成一个状态,然后都归属于本屌这个活动对象

 

二、状态划分

        抽象好活动对象的状态之后,就要准备规划每一个状态之间是怎么去转移的,这只是个准备阶段,其实就是具体每个状态该做些什么事,规划好,划分好。

 



        那我们一个个地细说:

        1.初始化状态:好比说,我今天来上班了,在正式进入本职工作之前,我要把我带来的早餐给消灭掉,然后,去厕所补个妆,顺顺发型什么的,然后配好咖啡,刷完手机上昨晚没看完的知乎日报······然后才正式转移到码代码的状态

        2.码代码状态:码代码就是本屌的本职工作了~码农不码?要你何用,但是,很不幸的是,老子在码代码的时候经常被各种事烦死,项目管理组那帮女汉子的咆哮、领导看你不积极抓取办公室训话、老大无聊要找你抽烟,而且,妈蛋这些都是不可抗拒力,而且还不得不满足他们或者她们,所以,昧着良心也要干啊~所以,如果被那些有事没事的“活动对象”发出那些烦人的事件消息,老子就要转移到对应的状态里面做那些该死的工作,what the fuck!!!

        3.走一个状态:本来我是在码代码的,但是老大实在寂寞难耐,就找本屌去抽烟了,那么我就从码代码状态转移到走一个状态

        4.调戏文员状态:本来我是在码代码的,但是我实在寂寞难耐,就想着去项目管理组调剂一下气氛,然后我就从码代码状态转移到调戏文员状态

        这里有个问题哈~和老大抽完烟之后也是可以顺便去项目管理组调戏一下小妹妹的;反过来,调戏完小妹妹之后也可以顺便和老大抽根事后烟的~嗯嗯,就是这样的

        5.被训话状态:本来老子好好地码代码,结果领导昨晚可能跟小三小费没谈拢,今天心情很不爽,移花接木找本屌的茬,训了本屌一顿,魂淡打个工真的是什么破事都可以碰到~what the fuck!!!

        这时候又有个问题了,通常被骂完之后也只能滚回去乖乖地工作了~哪有心情去调戏小妹妹;老大看到这样情况还哪敢找我去抽烟,所以只能回到老老实实的码代码的状态中来~

 

        到这里,状态之间怎么转移都妥妥滴规划好了~嗯嗯~就是这样的~

 

三、状态转移

        在状态划分阶段,就是“屌丝程序员”一天的所有流程状态,现在,我们以码代码为中心,讲一讲这个状态转移的破事

 


 

        这里再说一下,一个活动对象,每一个时间点,一定是停留在某个状态,是一定,比如本屌现在停留在“码代码”这个状态,在这个状态之中,活动对象,也就是本屌在这个状态时,可以接受4个事件信号:继续干、女汉子咆哮、老大邀请、领导不高兴。

        对于每一个事件信号被接受后,本屌都会转移到对应的状态,这里注意“继续干”这个信号,会停留在自己本身的状态,也就是不发生转移,到下面状态事件处理的环节,我们再详细讨论这个状态不转移的事件处理机制。

        对于“码代码”的状态的状态转移事件是这样规定,在其它状态中也是有这样的规定,就象状态划分的内容箭头标志,处在任何一个状态之中,当收到事件信号的时候,会在活动对象的状态之中发生状态转移

 

 

 

四、状态事件处理

        终于轮到最后一点:fsm的状态事件处理

 


 

        又找“码代码”这个状态来说破事了~

        上面状态转移这个章节,我们定义了几个会发生状态转移的事件消息,现在限于“码代码”这个状态中,比如说,码代码的工作很多,比如说我今天要写个linux下的tcp/ip的socket接收模块,是码代码的内容;比如说还要写一个opencv车牌识别的图像预处理的模块,也是码代码的内容;比如今天工作多得一B,还要对单片机写一个shell命令程序;那么,也还是码代码的内容,但是这是3个方面的工作,所以现在可以这样来处理了~定义“码代码”状态还可以接收3个关于码代码的事件信号,但是这3个信号不会发生活动对象的状态转移,就象上面图示一样~

        对于具体的执行过程是这样的

 


 

        第一,首先是活动对象或者中断给活动对象发送事件消息

        第二,处在某一个状态的活动对象得到事件消息,判断事件消息的类型

        第三,根据事件消息的类型执行状态处理函数,然后根据事件消息是否要发生活动对象的状态转移,执行完状态处理函数之后,或者停留在原来的状态,或者转移到新的状态

        第四,如果发生状态转移,之前我们讲过Raw-OS系统中有几个系统事件消息,ENTRY、INIT、EXIT、TIMEOUT,执行完第3步时,如果发生状态转移,那么要立即执行转移到的新状态的ENTRY事件,然后才稳定在转移到这个状态之中~

 

        嗯嗯~就是这样的~到这里为止就啰啰嗦嗦的讲完了fsm的一些概念,在进入系统代码实践篇的时候,我们来用Raw-OS的代码来实现上面的分析工作,共勉吧~骚年~

 

 

 

 

 

 

0 0