溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

發(fā)布時(shí)間:2021-08-30 16:22:40 來(lái)源:億速云 閱讀:277 作者:chen 欄目:編程語(yǔ)言

本篇內(nèi)容介紹了“C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!


什么是有限狀態(tài)機(jī)?

簡(jiǎn)單說(shuō)就是作一件事可能會(huì)經(jīng)過(guò)多個(gè)不同狀態(tài)的轉(zhuǎn)換, 轉(zhuǎn)換依賴(lài)于在不同時(shí)間發(fā)生的不同事件來(lái)觸發(fā), 舉個(gè)例子,比如 TCP的狀態(tài)轉(zhuǎn)換圖, 在實(shí)現(xiàn)上就可以用FSM.

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

傳統(tǒng)的實(shí)現(xiàn)方案

if...else : 搞一大堆if else, 一個(gè)函數(shù)寫(xiě)很長(zhǎng)很長(zhǎng)......

swich...case : 也搞一大堆一個(gè)函數(shù)寫(xiě)很長(zhǎng)很長(zhǎng)......

FSM的實(shí)現(xiàn)方案

根據(jù)具體的業(yè)務(wù)需要, 將業(yè)務(wù)的處理流程定義為一個(gè)狀態(tài)機(jī), 此狀態(tài)機(jī)中存在以下必要元素

  1. 根據(jù)業(yè)務(wù)需要, 拆解抽象出若干個(gè)不同狀態(tài) State, 并確定此狀態(tài)機(jī)的初始狀態(tài);

  2. 根據(jù)實(shí)現(xiàn)需要, 抽象出用于觸發(fā)狀態(tài)轉(zhuǎn)換的事件 Event;

  3. 為了處理一個(gè)Event, 需要定義狀態(tài)的轉(zhuǎn)換過(guò)程Transition;

  4. 狀態(tài)機(jī)要先判斷當(dāng)前所處的狀態(tài)是否與當(dāng)前發(fā)生的Event匹配(注意: 相同的狀態(tài)可能同時(shí)匹配多個(gè)Event)。

用張簡(jiǎn)圖來(lái)說(shuō)明一下

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)


  1. MachineSet可以同時(shí)管理多個(gè)Machine;

  2. 外部觸發(fā)的Event進(jìn)入到MachineSet的事件隊(duì)列;

  3. 事件隊(duì)列里的Event被順序處理, 被Dispatch到match的Machine;

  4. Machine根據(jù)當(dāng)前的所處的state和Event類(lèi)型來(lái)判斷當(dāng)前Event是否有效;

  5. 如果上面(4)中的Event有效, 則進(jìn)行狀態(tài)轉(zhuǎn)換;

  6. 狀態(tài)轉(zhuǎn)換具體來(lái)說(shuō)涉及到三個(gè)回調(diào)函數(shù):


            6.1 當(dāng)前state離開(kāi), 是第一個(gè)回調(diào),需要使用者根據(jù)實(shí)際需要處理;

            6.2 trasition這個(gè)轉(zhuǎn)換過(guò)程, 是第二個(gè)回調(diào);
            6.3 新state的進(jìn)入, 是第三個(gè)回調(diào);

一個(gè)簡(jiǎn)單的狀態(tài)機(jī),差不多就是上面這些內(nèi)容, 剩下的就是用程序語(yǔ)言把它實(shí)現(xiàn)出來(lái)了;

FSM的C++ 實(shí)現(xiàn)

一個(gè)用C++11實(shí)現(xiàn)的FSM的代碼

https://github.com/DavidLiuXh/kuafu

實(shí)現(xiàn)簡(jiǎn)介:

主要就是按deamo里的思路, 封裝了以下幾個(gè)模塊

MachineSet,
Machine,
Event,
Transition,
Predicate

對(duì)于Event的處理, 提供兩種方案:

  1. 直接使用MachineSet提供的StartBackground, 開(kāi)啟一個(gè)work thread, 在這個(gè)work thread中不斷從存儲(chǔ)event的fifo隊(duì)列中獲取event后dispatch到各個(gè)machine;

  2. 不使用MachineSet提供的event fifo, 實(shí)現(xiàn)自己的MachineSetHandler, 將其實(shí)例注冊(cè)到MachineSet, 從event的派發(fā);

一個(gè)具體的實(shí)現(xiàn)

我們來(lái)使用上面的FSM的實(shí)現(xiàn)來(lái)模擬一個(gè)用戶(hù)登陸的場(chǎng)景;

定義用到的Event和幾種不同的事件類(lèi)型

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

定義用到的狀態(tài)機(jī), 從 kuafu::StateMachine 繼承, 其中包括用過(guò)的幾種state和transitionC++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

在Birth()函數(shù)中構(gòu)造 state和 transition, Birth()是StateMachine的一個(gè)虛函數(shù), 每個(gè)用戶(hù)實(shí)現(xiàn)的Machine都需要實(shí)現(xiàn)它:

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

創(chuàng)建MachineSet, 并開(kāi)始event處理線(xiàn)程

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

創(chuàng)建用戶(hù)定義的Machine, 設(shè)置初始狀態(tài)

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

設(shè)置state和transition相應(yīng)的回調(diào)

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)

模擬event發(fā)生:

C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)


“C++怎么實(shí)現(xiàn)一個(gè)有限狀態(tài)機(jī)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

c++
AI