明らかにboostには、ステートマシン用の2つの個別のライブラリが含まれています。ステートチャートとメタステートマシン(MSM)です。タグラインは非常によく似た説明を与えます:
- Boost.Statechart-任意に複雑な有限状態マシンは、簡単に読み取りおよび保守可能なC ++コードで実装できます。
- Meta State Machine-表現力豊かなUML2有限状態マシン用の非常に高性能なライブラリ。
重要な違いは何か、2つを選択する際の考慮事項は何ですか?
明らかにboostには、ステートマシン用の2つの個別のライブラリが含まれています。ステートチャートとメタステートマシン(MSM)です。タグラインは非常によく似た説明を与えます:
重要な違いは何か、2つを選択する際の考慮事項は何ですか?
回答:
多くの関心があるように思われるので、私は(明らかに偏った)意見を述べさせてください。
MSMのレビュー中に投稿されたコメントを探すことで、自分をより良い意見にすることができます。この主題は開発者リストで多く議論されました。
クリストフがすでに述べたように、2つのライブラリの主な違いの1つは実行時のパフォーマンスです。MSMはおそらくここで得られる最高のものを提供しますが、Statechartは意識的にメモリとプロセッササイクルを交換して、より優れたスケーラビリティを実現します。
Boost.Statechartを使用すると、MSMではできない方法で、ステートマシンのレイアウト(状態、遷移)を複数の変換単位(cppファイル)に分散できます。これにより、大きなFSMの実装を保守しやすくし、MSMを使用する場合よりもはるかに高速にコンパイルできます。
MSMと比較したStatechartのパフォーマンスオーバーヘッドが実際にアプリケーションにとって重要であるかどうかは、アプリが1秒間に処理する必要があるイベントの数を自問すると、たいてい答えることは簡単です。
Boost.Statechartを使用して実装された適度に複雑なFSMを想定して、以下にいくつかの大まかな数値を示します。
CPU負荷に関しては、処理するイベントの数がこれらの数よりもはるかに少ない場合、MSMと比較したBoost.Statechartのオーバーヘッドはほとんど確実に目立ちません。数がはるかに多い場合は、MSMの方が間違いなく良いでしょう。
パフォーマンスとスケーラビリティのトレードオフの詳細については、http: //www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.htmlを参照してください。
独自のPPP実装をコーディングするときに、3つの理由でステートチャートを使用しました。1)ステートチャートの方が単純で、ドキュメントが明確です。2)私はUMLが本当に嫌いです:)
ブーストのドキュメントによると、MSMは少なくとも20倍高速ですが、大規模なFSMのコンパイルはかなり遅くなります。
少し前に、私はステートチャートから始めて、MSMに移行しました。単一スレッドからasioと組み合わせて使用する方が簡単だったからです。私は、ステートチャートとそのマルチスレッド機能をasioを使用してメッシュ化することができませんでした。これは、私にとっては、ステートチャートの初心者の理解の一部であったと考えられます。MSMはマルチスレッドに対応していないため、使いやすいことがわかりました。
Timのディスカッションへの遅れたエントリーへの回答(これは、Levからの非常に初期のコメントの1つにも対応しています)。
ブーストに提出されたときのステートチャート(実際のユースケースに基づく議論、実世界との相互作用、つまりI / Oについての議論)でのデストラクタからの出口の分離について主張した人の1人として、出口を置くことに問題があることに同意しますデストラクタのロジック。デビッド・アブラハムは、例外の安全性についても当然ながら説得力のある議論をしました。これらの理由により、ステートチャートでは、デストラクタにロジックを配置する必要はありませんが、通常のアドバイスに従ってロジックを配置できます。
ステートからの遷移の一部としてのみ実行されるロジック(ステートチャートオブジェクト全体の破棄ではなく)は、別のexit()アクションに分離できます(実行するリソースのクリーンアップも必要な場合)。
アクティブな状態(リソース)のない「薄い」状態の場合、実行するエントリー/終了アクションだけで、これらのアクションをctorとd'torで実行し、コンストラクターとデストラクターがスローしないことを確認できます。それらがする理由はありません-RAIIを実行する状態はありません-これらの場所でのエラー処理に適切なイベントを発生させることは悪ではありません。ただし、外部状態を変更する終了アクションをステートマシンの破壊時に実行するかどうかを検討する必要がある場合があります。この場合、発生させたくない場合は、それらを終了アクションに配置します...
ステートチャートはアクティベーションをオブジェクトのインスタンス化としてモデル化します。そのため、コンストラクターに実際の作業/アクティベーション/インスタンス化があり、状態に入ることができないような失敗が可能な場合、ステートチャートは、例外をイベント。これは、例外イベントを処理する外部状態を探す状態階層を処理する方法で処理されます。これは、スタックが呼び出しスタックベースの呼び出しモデルで展開される方法に似ています。
これはすべて十分に文書化されています。ドキュメントを読んで試してみることをお勧めします。デストラクタを使用して「ソフトウェアリソース」をクリーンアップし、終了アクションを実行して「実際の終了アクション」を実行することをお勧めします。
例外の伝播は、ステートチャートだけでなく、すべてのイベント駆動型環境で少し問題になることに注意してください。ステートチャートの設計に障害/エラーを推論して含めること、およびそれらを処理できない場合に限り、例外マッピングに別の方法で対処することが最善です。少なくともそれは私にとってはうまくいきます-ymmmv ...