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中的


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
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)
    }
}
最后编辑: Simon  文档更新时间: 2021-08-30 20:59   作者:Simon