Boost logo

Boost :

Subject: Re: [boost] Boost MSM parallel behavior with delayed self-transitions?
From: Danylo Malyuta (danylo.malyuta_at_[hidden])
Date: 2017-03-22 02:31:16


Here is sample code which attempts to replicate the diagram, but just for
the A state (the B state is not included, which would be trivial to do):

------------------------------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <thread>
#include <unistd.h>

#include <boost/msm/back/state_machine.hpp>
#include <boost/msm/front/state_machine_def.hpp>
#include <boost/msm/front/functor_row.hpp>

namespace msm = boost::msm;
namespace msmf = boost::msm::front;
namespace mpl = boost::mpl;

// Events
struct timeout {};

struct outer_:msmf::state_machine_def<outer_> {
  struct inner_:msmf::state_machine_def<inner_> {
    template <class Event, class Fsm>
    void on_entry(Event const&, Fsm&) {
      std::cout << "[state machine entry] inner" << std::endl;
    }
    struct A:msmf::state<> {
      template <class Event, class Fsm>
      void on_entry(Event const&, Fsm& f) {
        std::cout << "[state entry] A" << std::endl;
        stop_threads_ = false;
        thread_ = new std::thread(&A::func,this);
      }
      template <class Event, class Fsm>
      void on_exit(Event const&, Fsm&) {
        stop_threads_ = true;
        thread_->join(); // wait for threads to finish
        delete thread_;
        std::cout << "[state exit] A" << std::endl;
      }
      void func() {
        while (!stop_threads_) {
          usleep(1000000);
          std::cout << "Hello" << std::endl;
          // QUESTION: how to call process_event(timeout()) here?
        }
      }
     public:
      std::thread* thread_;
      bool stop_threads_;
    };
    struct Action {
      template <class Event, class Fsm, class SourceState, class
TargetState>
      void operator()(Event const&, Fsm&, SourceState&, TargetState&) {
        std::cout << "Trying again..." << std::endl;
      }
    };
    typedef A initial_state;
    struct transition_table:mpl::vector<
        msmf::Row <A,timeout,A,Action>
> {};
  };
  typedef msm::back::state_machine<inner_> inner;
  typedef inner initial_state;
};
typedef msm::back::state_machine<outer_> outer;

void waiting_thread() {
  while(true) {
    usleep(2000000);
  }
}

int main() {
  outer sm;
  sm.start();
  std::thread wait(waiting_thread);
  wait.join();
}
------------------------------------------------------------------------------------------------------------------------------------

Please see the comment `// QUESTION: how to call process_event(timeout())
here?`. How can I call process_event from inside the func() function in
Boost MSM?

Thank you,

Danylo.

On Tue, Mar 21, 2017 at 2:26 PM, degski via Boost <boost_at_[hidden]>
wrote:

> On 21 March 2017 at 14:35, Danylo Malyuta via Boost <boost_at_[hidden]
> >
> wrote:
>
> > Thanks for your input. I'm going to use std::thread for the parallel
> > functionality, I think. How stable/complete is Asynchronous? Can I rely
> on
> > it, or would I still have a moderate chance of running into bugs?
> >
>
> I still think you're over-engineering the thing, use std:thread and
> std::chrono. A simple loop will do what you desribed as your requirement,
> while limiting your dependencies... simpler generally means faster and
> easier to debug. Obviously this state, AB-state as I called it, can be part
> of a bigger picture, with (a) state machine(s).
>
> degski
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/
> mailman/listinfo.cgi/boost
>


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk