将多个MSM状态机耦合在一起

时间:2015-07-13 10:04:26

标签: c++ multithreading c++11 boost boost-msm

我的问题更像是一个架构问题。我有多个相同类型的状态机。说

controller_type1_sm controller1;
controller_type2_sm controller2;

std::array<worker1_sm,10> workers1;
std::array<worker2_sm,10> workers2;

现在当一个控制器发送消息时,我是否应该使用一个调度程序将一个名称或id调度到一个队列,该队列由一个在指定的msm上调用process_event()的线程工作?

当事件从公共基础派生时,事件可以保存在通用队列中,但process_event()需要知道它是什么类型的事件。访客班派遣他们?有更好的解决方案吗? 当我将事件限制为只有数字ID时,我可以删除很多问题,但另一方面,MSM需要类型而不是ID。

调用process_event()的线程需要知道它们所处的状态机的类型。模板显然......

编辑: 目标是解耦实现。

1 个答案:

答案 0 :(得分:1)

事实上,它简化了如何对队列中的不同消息进行排队,并在没有知道所有事件的访问者的情况下将其取回。

#include <queue>
#include <iostream>

struct runtime
{
    template <class T>
    void accept(const T& evt)
    {
        std::cout << "Accept: " << typeid(evt).name() << std::endl;
        // fsm.process_evt(evt);
    }
};
struct action
{
    virtual void operator()(runtime& rt) = 0;
};
template <class T>
struct carrier : action
{
    virtual void operator()(runtime& rt)
    {
        rt.accept(T());
    }
};

struct ev_test {};

int main(int argc, char** argv)
{
    using queue_t = std::deque<action*>;

    queue_t q;

    // capsulue the two functions
    runtime rt;
    carrier<int> f1;
    carrier<ev_test> f2;
    q.push_back(&f1);
    q.push_back(&f2);

    while (q.size())
    {
        auto& c = q.front();
        (*c)(rt);
        q.pop_front();
    }
}

在此示例中,“运行时”保存我的FSM。