FSM状态的实现技术

发布于 2024-09-06 14:14:35 字数 709 浏览 7 评论 0原文

您如何实现 FSM(编辑:有限状态机)状态? 我通常将 FSM 视为一组函数, 调度员, 和一个线程来指示当前的运行状态。 意思是,我阻止对代表的函数/函子的调用 州。

刚才我用一种不同的风格实现了一个, 我仍然用函数(对象)表示状态,但是线程 只是调用一个 state->step() 方法,该方法尝试返回 尽快。如果状态已经完成并且 应该发生转变,它相应地表明了这一点。 我将其称为“轮询”风格,因为函数大多看起来 就像:

void step()
{
  if(!HaveReachedGoal)
  {
    doWhateverNecessary();
    return; // get out as fast as possible
  }
  // ... test perhaps some more subgoals
  indicateTransition();
}

我知道它是 FSM 中的 FSM。

感觉比较简单,但是有一定的优点。 当线程被阻塞或处于某种状态时 while (!CanGoForward)checkGoForward(); 循环可能会很麻烦且难以操作, 轮询感觉更容易调试。 这是因为 FSM 对象在之后重新获得控制权 每一步,输出一些调试信息都是轻而易举的事。

好吧,我偏离了我的问题: 你们如何实现 FSM 的状态?

How do you go about implementing FSM(EDIT:Finite State Machine) states?
I usually think about an FSM like a set of functions,
a dispatcher,
and a thread as to indicate the current running state.
Meaning, I do blocking calls to functions/functors representing
states.

Just now I have implemented one in a different style,
where I still represent states with function(object)s, but the thread
just calls a state->step() method, which tries to return
as quickly as possible. In case the state has finished and a
transition should take place, it indicates that accordingly.
I would call this the 'polling' style since the functions mostly look
like:

void step()
{
  if(!HaveReachedGoal)
  {
    doWhateverNecessary();
    return; // get out as fast as possible
  }
  // ... test perhaps some more subgoals
  indicateTransition();
}

I am aware that it is an FSM within an FSM.

It feels rather simplistic, but it has certain advantages.
While a thread being blocked, or held in some kind of
while (!CanGoForward)checkGoForward();
loop can be cumbersome and unwieldy,
the polling felt much easier to debug.
That's because the FSM object regains control after
every step, and putting out some debug info is a breeze.

Well I am deviating from my question:
How do you implement states of FSMs?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

究竟谁懂我的在乎 2024-09-13 14:14:35

状态设计模式是实现 FSM 的一种有趣方式:

http://en.wikipedia.org/wiki /State_pattern

这是实现 FSM 的一种非常干净的方式,但它可能会很混乱,具体取决于 FSM 的复杂性(而不是状态的数量)。然而,优点是:

  • 消除了代码重复(尤其是 if/else 语句)
  • 更容易扩展新状态
  • 您的类具有更好的内聚性,因此所有相关逻辑都位于一个位置 - 这也将使您的代码更容易编写测试为了。

此站点上有 Java 和 C++ 实现:

http://www.vincehuston.org/dp /state.html

The state Design Pattern is an interesting way of implementing a FSM:

http://en.wikipedia.org/wiki/State_pattern

It's a very clean way of implementing the FSM but it can be messy depending on the complexity of your FSM (but not the amount of states). However, the advantages are that:

  • you eliminate code duplication (especially if/else statements)
  • It is easier to extend with new states
  • Your classes have better cohesion so all related logic is in one place - this should also make your code easier to writ tests for.

There is a Java and C++ implementation at this site:

http://www.vincehuston.org/dp/state.html

屋顶上的小猫咪 2024-09-13 14:14:35

总有一种我称之为“飞面面条怪”的 FSM 实现风格(FSM 风格的 FSM):使用大量的 goto。例如:

state1:
  do_something();
  goto state2;

state2:
  if (condition) goto state1;
  else           goto state3;

state3:
  accept;

非常好的意大利面条代码:-)

There’s always what I call the Flying Spaghetti Monster’s style of implementing FSMs (FSM-style FSMs): using lotsa gotos. For example:

state1:
  do_something();
  goto state2;

state2:
  if (condition) goto state1;
  else           goto state3;

state3:
  accept;

Very nice spaghetti code :-)

你如我软肋 2024-09-13 14:14:35

我把它做成一个表,内存中的平面数组,每个单元格都是一个状态。请查看废弃的 DFA 项目的 cvs 源。对于示例

class DFA {
    DFA();
    DFA(int mychar_groups,int mycharmap[256],int myi_state);
    ~DFA();
    void add_trans(unsigned int from,char sym,unsigned int to);
    void add_trans(unsigned int from,unsigned int symn,unsigned int to);
    /*adds a transition between state from to state to*/
    int add_state(bool accepting=false);
    int to(int state, int symn);
    int to(int state, char sym);
    void set_char(char used_chars[],int);
    void set_char(set<char> char_set);
    vector<int > table; /*contains the table of the dfa itself*/
    void normalize();

    vector<unsigned int> char_map;
    unsigned int char_groups; /*number of characters the DFA uses,
                    char_groups=0 means 1 character group is used*/
    unsigned int i_state; /*initial state of the DFA*/
    void switch_table_state(int first,int sec);
    unsigned int num_states;
    set<int > accepting_states;
};

但这是为了一个非常具体的需求(匹配正则表达式)

I did it as a table, a flat array in the memory, each cell is a state. Please have a look at the cvs source of the abandoned DFA project. For example:

class DFA {
    DFA();
    DFA(int mychar_groups,int mycharmap[256],int myi_state);
    ~DFA();
    void add_trans(unsigned int from,char sym,unsigned int to);
    void add_trans(unsigned int from,unsigned int symn,unsigned int to);
    /*adds a transition between state from to state to*/
    int add_state(bool accepting=false);
    int to(int state, int symn);
    int to(int state, char sym);
    void set_char(char used_chars[],int);
    void set_char(set<char> char_set);
    vector<int > table; /*contains the table of the dfa itself*/
    void normalize();

    vector<unsigned int> char_map;
    unsigned int char_groups; /*number of characters the DFA uses,
                    char_groups=0 means 1 character group is used*/
    unsigned int i_state; /*initial state of the DFA*/
    void switch_table_state(int first,int sec);
    unsigned int num_states;
    set<int > accepting_states;
};

But this was for a very specific need (matching regular expressions)

咽泪装欢 2024-09-13 14:14:35

我记得我的第一个 FSM 程序。我用 C 语言编写了一个非常简单的 switch 语句。从一种状态切换到另一种状态或进入下一种状态似乎很自然。

然后我开始使用表查找方法。我能够使用这种方法编写一些非常通用的编码风格。然而,当需求发生变化并且我必须支持一些额外的活动时,我遇到了几次麻烦。

我最近没有写任何FSM。我写的最后一个是针对 C++ 中的通信模块,其中我将“状态设计模式”与“命令模式”(操作)结合使用。

I remember my first FSM program. I wrote it in C with a very simple switch statement. Switching from one state to another or following through to the next state seemed natural.

Then I progressed to use a table lookup approach. I was able to write some very generic coding style using this approach. However, I was caught out a couple of times when the requirements changed and I have to support some extra events.

I have not written any FSMs lately. The last one I wrote was for a comms module in C++ where I used a "state design pattern" in conjunction with a "command pattern" (action).

那请放手 2024-09-13 14:14:35

如果您要创建复杂的状态机,那么您可能需要查看 SMC - 状态机编译器。它采用状态机的文本表示并将其编译为您选择的语言 - 它支持 Java、C、C++、C#、Python、Ruby、Scala 等。

If you are creating a complex state machine then you may want to check out SMC - the State Machine Compiler. This takes a textual representation of a state machine and compiles it into the language of your choice - it supports Java, C, C++, C#, Python, Ruby, Scala and many others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文