Boost MSM parallel behavior with delayed self-transitions?

Hi Danylo,
Hi community,
I am using Boost MSM (basic and functor front-ends) and am trying to implement the following state machine (https://i.stack.imgur.com/K79qk.png ):
Ok, State1 is itself a state machine (also called composite). See: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch02s02.html#d0e151 and: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch03s02.html#d0e529 Then you have 2 active states, which are called orthogonal regions. See: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch03s02.html#d0e577
I am using Boost MSM (basic and functor front-ends) and am trying to implement the following state machine: enter image description here
In words: < snip >
I would like to know the way to create this state machine in Boost MSM.
The above link has an example.
There are two tricks here which I cannot figure out how to do:
- Execution in parallel (i.e. running action_A does not stop running action_B at the same time)
It depends what you mean with "in parallel". Having 2 active states means that the actions execute only logically at the same time, meaning within the same process_event call. But as you have just one thread, they will execute after each other. If you mean in different threads, then no, the library does not support this. But my next library, Asynchronous does ( https://github.com/henry-ch/asynchronous). I have examples with state machines, timer, etc.
- Delayed transition (i.e. the transitions which happen after 2 seconds for state A and after 5 seconds for state B). Neither delay should be blocking! The transitions should just "fire" after this time.
Sorry, this is out of scope of the library as it would involve threads. You can do one of the following: - use your own timer (Boost.Asio offers one) and handle thread safety yourself. - have a look at Asynchronous. Sorry if it looks like advertising, but the library was written for this kind of things.
Thank you very much for helping,
Danylo.
HTH, Christophe

Hi Christophe, 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? Best, Danylo. PS. I love your documentation! What do you use for state machine diagrams - MagicDraw? On Tue, Mar 21, 2017 at 1:11 PM, Christophe Henry via Boost < boost@lists.boost.org> wrote:
Hi Danylo,
Hi community,
I am using Boost MSM (basic and functor front-ends) and am trying to implement the following state machine (https://i.stack.imgur.com/ K79qk.png ):
Ok, State1 is itself a state machine (also called composite). See: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch02s02.html#d0e151 and: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch03s02.html#d0e529
Then you have 2 active states, which are called orthogonal regions. See: http://www.boost.org/doc/libs/1_63_0/libs/msm/doc/HTML/ch03s02.html#d0e577
I am using Boost MSM (basic and functor front-ends) and am trying to implement the following state machine: enter image description here
In words: < snip >
I would like to know the way to create this state machine in Boost MSM.
The above link has an example.
There are two tricks here which I cannot figure out how to do:
- Execution in parallel (i.e. running action_A does not stop running action_B at the same time)
It depends what you mean with "in parallel". Having 2 active states means that the actions execute only logically at the same time, meaning within the same process_event call. But as you have just one thread, they will execute after each other. If you mean in different threads, then no, the library does not support this. But my next library, Asynchronous does ( https://github.com/henry-ch/asynchronous). I have examples with state machines, timer, etc.
- Delayed transition (i.e. the transitions which happen after 2 seconds for state A and after 5 seconds for state B). Neither delay should be blocking! The transitions should just "fire" after this time.
Sorry, this is out of scope of the library as it would involve threads. You can do one of the following: - use your own timer (Boost.Asio offers one) and handle thread safety yourself. - have a look at Asynchronous. Sorry if it looks like advertising, but the library was written for this kind of things.
Thank you very much for helping,
Danylo.
HTH, Christophe
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/ mailman/listinfo.cgi/boost

On 21 March 2017 at 14:35, Danylo Malyuta via Boost
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

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
On 21 March 2017 at 14:35, Danylo Malyuta via Boost
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

On 21 March 2017 at 20:31, Danylo Malyuta via Boost
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):
Just for fun I coded up the simple approach (no dependencies other than STL, no threads). Note that plenty of code/headers is/are dedicated to printing the current time, which for some reason or another is crazy complex for such a simple and common task. #include <chrono> #include <thread> #include <iostream> // Just to print the current time... #include <iomanip> // Just to print the current time... #include <ctime> // Just to print the current time... namespace sc = std::chrono; typedef sc::high_resolution_clock hrc; void a_action ( ) { std::time_t now_c = std::chrono::system_clock::to_time_t ( std::chrono::system_clock::now ( ) ); std::cout << "Trying A again at " << std::put_time ( std::localtime ( & now_c ), "%T" ) << "...\n"; } void b_action ( ) { std::time_t now_c = std::chrono::system_clock::to_time_t ( std::chrono::system_clock::now ( ) ); std::cout << "Trying B again at " << std::put_time ( std::localtime ( & now_c ), "%T" ) << "...\n"; } int main ( ) { sc::time_point < hrc > a_trigger = hrc::now ( ) + sc::seconds { 2 }, b_trigger = a_trigger + sc::seconds { 3 }; std::time_t now_c = std::chrono::system_clock::to_time_t ( std::chrono::system_clock::now ( ) ); std::cout << "Started at " << std::put_time ( std::localtime ( & now_c ), "%T" ) << '\n'; while ( true ) { if ( a_trigger < b_trigger ) { std::this_thread::sleep_until ( a_trigger ); a_action ( ); a_trigger += sc::seconds { 2 }; } else { std::this_thread::sleep_until ( b_trigger ); b_action ( ); b_trigger += sc::seconds { 5 }; } } return 0; } Sample output: Started at 08:56:34 Trying A again at 08:56:36... Trying A again at 08:56:38... Trying B again at 08:56:39... Trying A again at 08:56:40... Trying A again at 08:56:42... Trying B again at 08:56:44... Trying A again at 08:56:44... Trying A again at 08:56:46... Trying A again at 08:56:48... Trying B again at 08:56:49... Trying A again at 08:56:50... Trying A again at 08:56:52... Trying B again at 08:56:54... Trying A again at 08:56:54... Trying A again at 08:56:56... Trying A again at 08:56:58... degski
participants (3)
-
Christophe Henry
-
Danylo Malyuta
-
degski