天天看點

狀态機的了解和筆記

數電的狀态機\C語言的狀态機
狀态機由狀态寄存器群組合邏輯電路構成,能夠根據控制信号按照預先設定的狀态進行狀态轉換,是協調相關信号動作、完成特定操作的控制中心。***有限狀态機簡稱為FSM***,主要分為2大類:
           

第一類:若輸出隻和狀态有關而與輸入無關則稱為Moore狀态機。

第二類:若輸出不僅和狀态有關而且和輸入有關系,則稱為Mealy型狀态機。

就是狀态轉移圖。

舉例:人有三個狀态:健康,感冒,康複中。觸發的條件有:淋雨,吃藥,打針,休息。

是以狀态機就是健康-(休息)->健康;健康-(淋雨)->感冒;感冒-(打針)->健康;感冒-(吃藥)->康複中;康複中-(休息)->健康,等等。就是這樣狀态在不同的條件下跳轉到自己或不同狀态的圖。

狀态機綜述

關于狀态機的一個極度确切的描述是它是一個有向圖形,由一組節點和一組相應的轉移函數組成。狀态機通過響應一系列事件而“運作”。每個事件都在屬于“目前” 節點的轉移函數的控制範圍内,其中函數的範圍是節點的一個子集。函數傳回“下一個”(也許是同一個)節點。這些節點中至少有一個必須是終态。當到達終态, 狀态機停止

包含一組狀态集,一個起始狀态,一組輸入符号集,一個映射輸入符号和目前狀态到下一狀态的轉換函數的計算模型。當輸入符号串,模型随機進入起始狀态。他要改變到新的狀态,依賴于轉換函數。在有限狀态機中,會有許多變量,例如:狀态機有很多與動作轉換(Mealy)或狀态關聯(Moore)動作,多起始狀态,基于沒有輸入符号的轉換,或者指定符号和狀态(非定有限狀态機)的多個轉換,指派給接收狀态(識别者)的一個或多個狀态。

傳統應用程式的控制流程基本是順序的:遵循事先設定的邏輯,從頭到尾地執行。很少有事件能改變标準執行流程;而且這些事件主要涉及異常情況。“指令行實用程式”是這種傳統應用程式的典型例子。

另一類應用程式由外部發生的事件來驅動——換言之,事件在應用程式之外生成,無法由應用程式或程式員來控制。具體需要執行的代碼取決于接收到的事件,或者它 相對于其他事件的抵達時間。是以,控制流程既不能是順序的,也不能是事先設定好的,因為它要依賴于外部事件。事件驅動的GUI應用程式是這種應用程式的典 型例子,它們由指令和選擇(也就是使用者造成的事件)來驅動。

Web應用程式由送出的表單和使用者請求的網頁來驅動,它們也可劃歸到上述類别。但是,GUI應用程式對于接收到的事件仍有一定程度的控制,因為這些事件要依賴于向使用者顯示的視窗和控件,而視窗和控件是由程式員控制的。Web應用 程式則不然,因為一旦使用者采取不在預料之中的操作(比如使用浏覽器的曆史記錄、手工輸傳入連結接以及模拟一次表單送出等等),就很容易打亂設計好的應用程式邏輯。

顯然,必須采取不同的技術來處理這些情況。它能處理任何順序的事件,并能提供有意義的響應——即使這些事件發生的順序和預計的不同。***有限狀态機***正是為了滿足這方面的要求而設計的。

有限狀态機是一種概念性機器,它能采取某種操作來響應一個外部事件。具體采取的操作不僅能取決于接收到的事件,還能取決于各個事件的相對發生順序。之是以能 做到這一點,是因為機器能跟蹤一個内部狀态,它會在收到事件後進行更新。為一個事件而響應的行動不僅取決于事件本身,還取決于機器的内部狀态。另外,采取 的行動還會決定并更新機器的狀态。這樣一來,任何邏輯都可模組化成一系列事件/狀态組合。

[2]

狀态機可歸納為4個要素,即現态、條件、動作、次态。這樣的歸納,主要是出于對狀态機的内在因果關系的考慮。“現态”和“條件”是***因***,“動作”和“次态”是***果***。詳解如下:

①現态:是指目前所處的狀态。

②條件:又稱為“事件”,當一個條件被滿足,将會觸發一個動作,或者執行一次狀态的遷移。

③動作:條件滿足後執行的動作。動作執行完畢後,可以遷移到新的狀态,也可以仍舊保持原狀态。動作不是必需的,當條件滿足後,也可以不執行任何動作,直接遷移到新狀态。

④次态:條件滿足後要遷往的新狀态。“次态”是相對于“現态”而言的,“次态”一旦被激活,就轉變成新的“現态”了。

後面是重點

有限狀态機

有限狀态機FSM

思想廣泛應用于硬體控制電路設計,也是軟體上常用的一種處理方法(軟 件上稱為FMM–有限消息機)。它把複雜的控制邏輯分解成***有限個穩定狀态***,在每個狀态上判斷事件,變連續處理為離散數字處理,符合計算機的工作特點。同時,因為有限狀态機具有有限個狀态,是以可以在實際的工程上實作。但這并不意味着其隻能進行有限次的處理,相反,有限狀态機是***閉環系統***,有限無窮,可以用有限的狀态,處理無窮的事務。

有限狀态機有兩種寫法:

豎着的那種寫法 還有橫着的狀态機,是用函數指針的形式來實作的,其實速度是一樣的

現在的編譯器 都會對switch進行優化的,

不過橫着的那種狀态機 可維護型更高,隻需要增加 功能即可,不用每增加一次就修改switch的語句。

注:這個雖然使用了目前狀态實作不同的功能但是,他沒有轉換到其他狀态。是以和有限狀态機是有差別的

狀态機的可以用兩種方法實作:

(1)豎着寫(在狀态中判斷事件,即先通過switch來判斷狀态的,然後再通過不同的case裡的時間來執行動作)

(2) 橫着寫(在事件中判斷狀态,即先發生事件,然後執行函數,把狀态傳遞進去,然後根據不同的狀态來執行不同的事件)

(下面的說法其實有些過時了,現在的編譯器一般會優化豎着寫的情況,但是為了可讀性和習慣,一般使用第二種方法。)

豎着寫和橫着寫,實作的功能是完全相同的,但是,橫着寫的效果明顯好于豎着寫的效果。理由如下:

1、豎着寫隐含了優先級排序(其實各個時間是同優先級的),排在前面的事件判斷将毫無疑問地優先于排在後面的事件判斷。這種If/else if寫法上的限制将破壞事件原有的關系。而橫着寫不存在此問題。

2、由于處于每個狀态時的事件數目不一緻,而且事件發生的事件是随機的,無法預先确定,導緻豎着寫淪落為順序查詢方式,結構上的缺陷使得大量時間被浪費。對于橫着寫,在某個時間點,狀态時唯一确定的,在事件裡查找狀态隻要使用switch語句,就能一步定位到相應的狀态,延遲時間可以預先準确估算,而且在事件發生時,調用事件函數,在函數裡查找唯一确定的狀态,并根據其執行動作和狀态轉移的思路清晰簡潔,效率高,富有美感。

引自 :百度百科   非原創
           

繼續閱讀