Apparemment, boost contient deux bibliothèques distinctes pour les machines à états: Statechart et Meta State Machine (MSM). Les slogans donnent des descriptions très similaires:
- Boost.Statechart - Des machines à états finis arbitrairement complexes peuvent être implémentées dans un code C ++ facilement lisible et maintenable.
- Meta State Machine - Une bibliothèque très performante pour les machines à états finis UML2 expressives.
Savez-vous quelles sont les principales différences et quelles sont les considérations à prendre en compte pour choisir entre les deux?
c++
boost
state-machine
boost-statechart
boost-msm
FeuAphis
la source
la source
Réponses:
Comme il semble y avoir beaucoup d'intérêt, permettez-moi de donner mon avis (évidemment biaisé), qui doit donc être pris avec un grain de sel:
Vous pouvez vous faire une meilleure opinion en recherchant les commentaires postés lors de l'examen de MSM. Ce sujet a été beaucoup discuté sur la liste des développeurs.
la source
Comme Christophe l'a déjà mentionné, l'une des principales différences entre les deux bibliothèques est la performance d'exécution. Alors que MSM offre probablement le meilleur que vous puissiez obtenir ici, Statechart échange consciemment les cycles de mémoire et de processeur pour une meilleure évolutivité.
Avec Boost.Statechart, vous pouvez répartir la mise en page (c'est-à-dire les états, les transitions) de votre machine d'état sur plusieurs unités de traduction (fichiers cpp) d'une manière que vous ne pouvez pas avec MSM. Cela vous permet de rendre l'implémentation de grands FSM plus facile à gérer et d'obtenir une compilation beaucoup plus rapide qu'avec MSM.
Il est souvent assez facile de savoir si la surcharge de performance de Statechart par rapport à MSM sera réellement significative pour votre application lorsque vous vous demandez combien d'événements votre application devra traiter par seconde.
En supposant un FSM modérément complexe implémenté avec Boost.Statechart, voici quelques chiffres approximatifs:
En ce qui concerne la charge du processeur, si le nombre d'événements à traiter est bien inférieur à ces chiffres, la surcharge de Boost.Statechart par rapport à MSM ne sera presque certainement pas perceptible. Si le nombre est beaucoup plus élevé, vous êtes certainement mieux avec MSM.
Des informations plus détaillées sur les compromis performances / évolutivité sont disponibles ici: http://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html
la source
En codant ma propre implémentation PPP, j'ai utilisé Statechart pour trois raisons: 1) Statechart est plus simple et a une documentation plus claire; 2) Je n'aime vraiment pas UML :)
Les documents Boost indiquent que MSM est au moins 20 fois plus rapide, mais se compile assez lentement pour les gros FSM.
la source
Il y a quelque temps, j'ai commencé avec Statechart et je suis passé à MSM car il était plus facile à utiliser avec asio à partir d'un seul thread. Je n'ai pas réussi à mailler Statechart et ses capacités multithreading avec mon utilisation d'Asio - c'était probablement une sorte d'incompréhension débutant de Statechart de ma part. J'ai trouvé que MSM était plus facile à utiliser car il n'abordait pas le multithreading.
la source
En réponse à l'entrée tardive de Tim dans la discussion (qui répond également à l'un des tout premiers commentaires de Lev).
En tant que l'un de ceux qui ont plaidé pour la séparation de la sortie des destructeurs dans le statechart (argument basé sur un cas d'utilisation réel, à propos de l'interaction avec le monde réel, c'est-à-dire les E / S) il y a longtemps quand il a été soumis à Boost, je suis d'accord qu'il peut y avoir des problèmes pour mettre exit logique dans les destructeurs. Sans surprise, David Abrahams a également présenté des arguments convaincants concernant la sécurité des exceptions. Pour ces raisons, Statechart ne vous oblige pas à mettre de la logique dans les destructeurs - mais il vous le permet - avec les conseils habituels.
La logique qui ne devrait jamais s'exécuter que dans le cadre d'une transition hors d'un état (et non la destruction de l'objet d'états dans son ensemble) peut (et devrait s'il y a aussi un nettoyage de ressources à faire) être séparée en une action exit () distincte.
Pour un état "léger" sans état actif (ressources), juste des actions d'entrée / sortie à effectuer, vous pouvez effectuer ces actions dans ctor et d'tor et vous assurer que le constructeur et le destructeur ne lancent pas. Il n'y a aucune raison pour eux - il n'y a pas d'état sur lequel exécuter RAII - il n'y a aucun mal à ce que la gestion des erreurs dans ces endroits déclenche des événements appropriés. Vous devrez peut-être encore déterminer si vous voulez que les actions de sortie qui modifient l'état externe s'exécutent sur la destruction de la machine à états ... et les mettre en action de sortie si vous ne voulez pas qu'elles se produisent dans ce cas ...
Statechart modélise l'activation comme instanciation d'un objet, donc si votre constructeur a un vrai travail / activation / instanciation à faire et s'il est capable d'échouer de telle sorte que l'état ne puisse pas être entré Statechart prend en charge cela en vous donnant la possibilité de mapper une exception à un un événement. Ceci est géré d'une manière qui travaille la hiérarchie des états à la recherche d'un état externe qui gère l'événement d'exception, analogue à la façon dont la pile se serait déroulée pour un modèle d'appel basé sur une pile d'appels.
Tout cela est bien documenté - je vous suggère de lire la documentation et de l'essayer. Je vous suggère d'utiliser des destructeurs pour nettoyer les «ressources logicielles» et les actions de sortie pour effectuer des «actions de sortie du monde réel».
Il est à noter que la propagation d'exceptions est un peu un problème dans tous les environnements pilotés par les événements, pas seulement dans les statecharts. Il est préférable de raisonner et d'inclure les défauts / erreurs dans la conception de votre diagramme d'états et si et seulement si vous ne pouvez pas les gérer d'une autre manière, utilisez le mappage d'exceptions. Au moins cela fonctionne pour moi - ymmmv ....
la source