首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解hello_world boost sml状态机库

理解hello_world boost sml状态机库
EN

Stack Overflow用户
提问于 2021-02-15 03:17:03
回答 1查看 637关注 0票数 1

下面是boost sml C++库的hello示例:https://boost-ext.github.io/sml/examples.html#hello-world

代码语言:javascript
复制
// $CXX -std=c++14 hello_world.cpp
#include <boost/sml.hpp>
#include <cassert>

namespace sml = boost::sml;

namespace {
struct release {};
struct ack {};
struct fin {};
struct timeout {};

const auto is_ack_valid = [](const ack&) { return true; };
const auto is_fin_valid = [](const fin&) { return true; };

const auto send_fin = [] {};
const auto send_ack = [] {};

#if !defined(_MSC_VER)
struct hello_world {
  auto operator()() const {
    using namespace sml;
    return make_transition_table(
      *"established"_s + event<release> / send_fin = "fin wait 1"_s,
       "fin wait 1"_s + event<ack> [ is_ack_valid ] = "fin wait 2"_s,
       "fin wait 2"_s + event<fin> [ is_fin_valid ] / send_ack = "timed wait"_s,
       "timed wait"_s + event<timeout> / send_ack = X
    );
  }
};
}

int main() {
  using namespace sml;

  sm<hello_world> sm;
  static_assert(1 == sizeof(sm), "sizeof(sm) != 1b");
  assert(sm.is("established"_s));

  sm.process_event(release{});
  assert(sm.is("fin wait 1"_s));

  sm.process_event(ack{});
  assert(sm.is("fin wait 2"_s));

  sm.process_event(fin{});
  assert(sm.is("timed wait"_s));

  sm.process_event(timeout{});
  assert(sm.is(X));  // released
}
#else
class established;
class fin_wait_1;
class fin_wait_2;
class timed_wait;

struct hello_world {
  auto operator()() const {
    using namespace sml;
    return make_transition_table(
      *state<established> + event<release> / send_fin = state<fin_wait_1>,
       state<fin_wait_1> + event<ack> [ is_ack_valid ] = state<fin_wait_2>,
       state<fin_wait_2> + event<fin> [ is_fin_valid ] / send_ack = state<timed_wait>,
       state<timed_wait> + event<timeout> / send_ack = X
    );
  }
};
}

int main() {
  using namespace sml;

  sm<hello_world> sm;
  assert(sm.is(state<established>));

  sm.process_event(release{});
  assert(sm.is(state<fin_wait_1>));

  sm.process_event(ack{});
  assert(sm.is(state<fin_wait_2>));

  sm.process_event(fin{});
  assert(sm.is(state<timed_wait>));

  sm.process_event(timeout{});
  assert(sm.is(X));  // released
}
#endif

据我所知,_s创建了一个具有名称的状态,并且可以在状态上发生事件,这会将状态机发送到另一个状态。

让我们看看hello_world状态机:

代码语言:javascript
复制
struct hello_world {
  auto operator()() const {
    using namespace sml;
    return make_transition_table(
      *"established"_s + event<release> / send_fin = "fin wait 1"_s,
       "fin wait 1"_s + event<ack> [ is_ack_valid ] = "fin wait 2"_s,
       "fin wait 2"_s + event<fin> [ is_fin_valid ] / send_ack = "timed wait"_s,
       "timed wait"_s + event<timeout> / send_ack = X
    );
  }
};

如果我正确理解,这意味着当状态机处于状态established并接收到事件release时,它将进入状态fin wait 1send_fin是什么?**state<established> + event<release> / send_fin = state<fin_wait_1>中是什么?这种疯狂的语法是什么?我认为+/=只是简单的覆盖运算符,可以轻松地创建转换表。另外,什么是is_ack_valid

我对*的猜测是,它指定了状态机的乞讨状态。

事件是会发生的事情。

EN

回答 1

Stack Overflow用户

发布于 2022-02-02 03:54:27

--如果我理解正确,这意味着当状态机处于已建立并接收事件释放的状态时,它将进入状态fin等待1。

真的

,send_fin是什么?

在州内接收释放时触发的一种动作。在这个例子中,它是一个绝对什么都不做的lambda。*耸耸肩:

* in *state + event / send_fin = state是什么?这种疯狂的语法是什么?我认为+,/ and =是简单的覆盖运算符,可以轻松地创建转换表。

*是初始状态,您是正确的。值得注意的是,一个复杂的转换表实际上可以跟踪多个子计算机,因此每个部分都有多个*。

我非常怀疑您是正确的,操作符重载驱动了语法。说到设计,它也是通过TMP优化的编译时间。

也是,is_ack_valid是什么?

在事件后封装在括号中的表达式称为守护。评估为false的保护将防止任何操作或转换发生,即使接收到了该事件。

在这个简单的例子中,lambda总是返回true,所以它在编写时是无用的。一个更完整的示例将实际检查ack上的某些内容。

我猜*是它指定了状态机的开始状态。

真的

事件是会发生的事情。

好的。没有任何价值,它们是强类型的,并且被有意地发送到状态机。

不请自来的评论如下.

我已经在工作中大量使用了SML。一开始,这是一件需要学习的事情,因为我已经在用消防水管喝水了。

在经历了一段时间之后,我要说的积极的事情是,它可以非常简洁地表示复杂的流控制,而且它是非常有效的。

如果您有机会观看克里斯的2019年c++现在谈话,他的TCP连接状态管理是一个很好的例子,从这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66202301

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档