显然boost包含两个独立的状态机库:Statechart和Meta State Machine(MSM)。标语给出了非常相似的描述:
- Boost.Statechart-可以用易于阅读和维护的C ++代码实现任意复杂的有限状态机。
- 元状态机-用于表达性UML2有限状态机的非常高性能的库。
您知道两者之间的主要区别是什么,以及在两者之间进行选择时需要考虑的因素?
显然boost包含两个独立的状态机库:Statechart和Meta State Machine(MSM)。标语给出了非常相似的描述:
您知道两者之间的主要区别是什么,以及在两者之间进行选择时需要考虑的因素?
Answers:
似乎引起了很大的兴趣,请允许我发表我的(显然有偏见的)观点,因此应该带一点盐:
通过在MSM审阅期间查找张贴的评论,可以使自己成为更好的意见。开发人员列表中对该主题进行了很多讨论。
正如Christophe已经提到的,两个库之间的主要区别之一是运行时性能。尽管MSM可能会为您提供最好的解决方案,但Statechart会自觉地将内存和处理器周期换为更好的可伸缩性。
借助Boost.Statechart,您可以将状态机的布局(即状态,过渡)分布在MSM无法实现的多个转换单元(cpp文件)上。与MSM相比,这使您可以使大型FSM的实现更易于维护,并获得更快的编译速度。
当您问自己自己的应用程序每秒必须处理多少个事件时,通常很容易回答Statechart与MSM相比的性能开销对您的应用程序是否真正重要。
假设使用Boost.Statechart实现了一个中等复杂的FSM,以下是一些基本数字:
关于CPU负载,如果要处理的事件数比这些数少得多,则与MSM相比,Boost.Statechart开销几乎肯定不会引起注意。如果这个数字高得多,那么使用MSM一定会更好。
有关性能/可伸缩性折衷的更多详细信息,请参见:http : //www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html
前一段时间,我开始使用Statechart并移至MSM,因为它更易于从单个线程与asio结合使用。我没有通过使用asio来使Statechart及其多线程功能结合在一起-对我而言,这可能是对Statechart的某种新手理解。我发现MSM更容易使用,因为它没有解决多线程问题。
为了回应Tim迟到的讨论(这也解决了Lev的早期评论之一)。
正如那些在状态图中主张将出口与析构函数分离的人(基于真实用例的论据,关于与现实世界(即I / O)的交互)早在提交给Boost时一样,我同意在退出时可能存在问题析构函数中的逻辑。大卫·亚伯拉罕(David Abrahams)毫不奇怪地就异常安全性也提出了有说服力的论据。出于这些原因,Statechart不需要您将逻辑放在析构函数中-但它允许您-使用通常的建议。
只能将逻辑作为状态转换的一部分运行(而不是整个状态图对象的销毁),可以将逻辑分离为单独的exit()动作(如果还需要进行资源清理)。
对于没有活动状态(资源)的“瘦”状态,只需执行进入/退出操作,就可以在ctor和d'tor中执行这些操作,并确保构造函数和析构函数不会抛出。他们没有理由-没有执行RAII的状态-在这些地方进行错误处理引发适当的事件没有任何邪恶。您可能仍然需要考虑是否要使改变外部状态的退出操作在破坏状态机的情况下运行,如果不希望在这种情况下发生,请将它们置于退出操作中。
Statechart将激活建模为对象的实例化,因此,如果您的构造函数有实际工作/激活/实例化要做,并且能够失败而无法输入状态,则Statechart通过提供将异常映射到对象的能力来支持这一点。事件。这是通过处理状态层次结构以查找处理异常事件的外部状态的方式进行处理的,类似于为基于调用堆栈的调用模型取消堆栈的方式。
一切都有据可查-我建议您阅读文档并尝试一下。我建议您使用析构函数来清理“软件资源”并退出操作以执行“实际退出操作”。
值得注意的是,在所有事件驱动的环境中,不仅仅是状态图,异常传播都是一个问题。最好在状态图设计中进行推理,并将故障/错误包括在内,并且仅当您无法处理它们时,才可以采用异常映射的另一种方式。至少对我有用-ymmmv ....