FSM:有限狀態機又簡稱FSM(Finite-State Machine的首字母縮寫)。這個在離散數學里學過了,它是計算機領域中被廣泛使用的數學概念。是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。編譯原理學得好的童鞋應該對FSM不陌生,因為編譯器就用了FMS來做詞法掃描時的狀態轉移。
所謂有限狀態機,就是由有限個狀態組成的機器。再看上面舉到的例子:人就是一部機器,能感知三種狀態(冷、餓、困)。由於氣溫降低所以人會覺得冷;由於到了吃飯的時間所以覺得餓;由於晚上12點所以覺得困。狀態的產生以及改變都是由某種條件的成立而出現的。不考慮FSM的內部結構時,它就像是一個黑箱子,如下圖:
左邊是輸入一系列條件,FSM通過判定,然后輸出結果。
GitHub上 FSM的地址:https://github.com/looplab/fsm
以下為fsm的example:
FSM for Go
FSM is a finite state machine for Go.
It is heavily based on two FSM implementations:
-
Javascript Finite State Machine, https://github.com/jakesgordon/javascript-state-machine
-
Fysom for Python, https://github.com/oxplot/fysom (forked at https://github.com/mriehl/fysom)
For API docs and examples see http://godoc.org/github.com/looplab/fsm
Basic Example
From examples/simple.go:
package main
import (
"fmt"
"github.com/looplab/fsm"
)
func main() {
fsm := fsm.NewFSM(
"closed",
fsm.Events{
{Name: "open", Src: []string{"closed"}, Dst: "open"},
{Name: "close", Src: []string{"open"}, Dst: "closed"},
},
fsm.Callbacks{},
)
fmt.Println(fsm.Current())
err := fsm.Event("open")
if err != nil {
fmt.Println(err)
}
fmt.Println(fsm.Current())
err = fsm.Event("close")
if err != nil {
fmt.Println(err)
}
fmt.Println(fsm.Current())
}
Usage as a struct field(hyperledger中使用的方式,用來創建peer的handle)
例如:peer/start.go中的
1.
peerServer, err = peer.NewPeerWithEngine(secHelperFunc, helper.GetEngine)
func NewPeerWithEngine(secHelperFunc func() crypto.Peer, engFactory EngineFactory) (peer *Impl, err error) {
peer.handlerFactory = peer.engine.GetHandlerFactory()
func NewConsensusHandler(coord peer.MessageHandlerCoordinator,stream peer.ChatStream, initiatedStream bool) (peer.MessageHandler, error)
func (p *Impl) chatWithSomePeers(addresses []string)
p.chatWithPeer(address) 里面會使用上面的peer.handlerFactory 來創建handle
2.
peer.NewPeerWithHandler(secHelperFunc, peer.NewPeerHandler) //生成nvp節點,是利用handler
From examples/struct.go:
package main
import (
"fmt"
"github.com/looplab/fsm"
)
type Door struct {
To string
FSM *fsm.FSM
}
func NewDoor(to string) *Door {
d := &Door{
To: to,
}
d.FSM = fsm.NewFSM(
"closed",
fsm.Events{
{Name: "open", Src: []string{"closed"}, Dst: "open"},
{Name: "close", Src: []string{"open"}, Dst: "closed"},
},
fsm.Callbacks{
"enter_state": func(e *fsm.Event) { d.enterState(e) },
},
)
return d
}
func (d *Door) enterState(e *fsm.Event) {
fmt.Printf("The door to %s is %s\n", d.To, e.Dst)
}
func main() {
door := NewDoor("heaven")
err := door.FSM.Event("open")
if err != nil {
fmt.Println(err)
}
err = door.FSM.Event("close")
if err != nil {
fmt.Println(err)
}
}

