151

ブーストには、ステート マシン用の 2 つの個別のライブラリが含まれているようです。StatechartMeta State Machine (MSM) です。キャッチフレーズは、非常によく似た説明を提供します。

  • Boost.Statechart - 任意の複雑な有限状態マシンを、読みやすく保守しやすい C++ コードで実装できます。
  • Meta State Machine - 表現力豊かな UML2 有限状態マシン用の非常に高性能なライブラリ.

主な違いは何か、また、この 2 つを選択する際の考慮事項は何ですか?

4

5 に答える 5

123

多くの関心が寄せられているように思われるので、私の (明らかに偏った) 意見を述べさせてください。

  • MSMははるかに高速です
  • MSM は RTTI や仮想的なものを必要としません
  • MSM には、より完全な UML2 サポートがあります (たとえば、内部遷移、UML 準拠の直交領域)。
  • MSM は記述言語 (実際にはいくつか) を提供します。たとえば、eUML フロントエンドを使用すると、トランジションはソース + イベント [ガード] / アクション == ターゲットとして記述できます。
  • MSM は、より大きなステート マシンに対してコンパイラを苦しめます。そのため、最新のコンパイラ (g++ >= 4.x、VC >= 9) が必要になります。

MSM のレビュー中に投稿されたコメントを探すことで、より良い意見を得ることができます。このテーマは、開発者リストでよく議論されました。

于 2010-11-26T08:18:52.483 に答える
118

Christophe が既に述べたように、2 つのライブラリの主な違いの 1 つは実行時のパフォーマンスです。MSM はおそらくここで得られる最高のものを提供しますが、Statechart はメモリとプロセッサ サイクルを意識的にトレードオフして、スケーラビリティを向上させます。

Boost.Statechart を使用すると、MSM ではできない方法で、ステート マシンのレイアウト(つまり、状態、遷移) を複数の翻訳単位 (cpp ファイル) に広げることができます。これにより、大規模な FSM の実装をより保守しやすくし、MSM よりもはるかに高速にコンパイルできます。

MSM と比較した Statechart のパフォーマンス オーバーヘッドがアプリケーションにとって実際に重要であるかどうかは、多くの場合、アプリが 1 秒あたりに処理する必要があるイベントの数を自問すると、非常に簡単に答えられます。

Boost.Statechart で実装された適度に複雑な FSM を想定して、いくつかの概算値を次に示します。

  • 現在のほとんどの PC ハードウェアは、1 秒あたり 100,000 件を超えるイベントに容易に対応できます。
  • リソースに非常に制約のあるハードウェアでも、1 秒あたり数百のイベントを処理できます。

CPU 負荷に関しては、処理するイベントの数がこれらの数値よりもはるかに少ない場合、MSM と比較した Boost.Statechart のオーバーヘッドはほぼ確実に目立たなくなります。数値がはるかに高い場合は、MSM の方が確実に優れています。

パフォーマンスとスケーラビリティのトレードオフの詳細については、 http ://www.boost.org/doc/libs/1_45_0/libs/statechart/doc/performance.html を参照してください。

于 2010-11-30T07:41:41.140 に答える
13

私自身の PPP 実装をコーディングする際に、ステートチャートを使用した理由は次の 3 つです。2) 私はUMLが本当に嫌いです:)

Boost のドキュメントによると、MSM は少なくとも 20 倍高速ですが、大規模な FSM ではコンパイルがかなり遅くなります。

于 2010-11-25T13:11:45.747 に答える
4

しばらく前に私は Statechart から始めて、シングル スレッドから asio と組み合わせて使用​​する方が簡単だったので MSM に移行しました。私は asio を使用して Statechart とそのマルチスレッド機能をうまく噛み合わせることができませんでした。これは、私の Statechart を理解していないある種の初心者だった可能性があります。MSM はマルチスレッドに対応していないため、使いやすいことがわかりました。

于 2012-02-09T19:03:20.980 に答える
3

議論への Tim の遅れたエントリへの回答 (これは、Lev からの非常に初期のコメントの 1 つにも対応しています)。

ステートチャートでデストラクタから exit を分離することを主張した人の 1 人として (実際のユースケースに基づく議論、現実世界との相互作用、つまり I/O について) ずっと前に Boost に提出されたとき、exit を配置する際に問題がある可能性があることに同意します。デストラクタのロジック。当然のことながら、David Abrahams は、例外の安全性に関しても説得力のある議論を行いました。これらの理由から、Statechart では、ロジックをデストラクタに入れる必要はありませんが、通常のアドバイスに従ってデストラクタに入れることができます。

状態からの遷移の一部としてのみ実行する必要がある (statechart オブジェクト全体の破棄ではない) ロジックは、個別の exit() アクションに分離できます (実行するリソースのクリーンアップもある場合は実行する必要があります)。

アクティブな状態 (リソース) がなく、実行するエントリ/終了アクションのみの「薄い」状態の場合、ctor と d'tor でこれらのアクションを実行し、コンストラクタとデストラクタがスローしないようにすることができます。それらに理由はありません - RAII を実行する状態はありません - これらの場所でのエラー処理が適切なイベントを発生させることに悪はありません。ただし、外部状態を変更する終了アクションをステートマシンの破壊で実行するかどうかを検討する必要がある場合があります...そして、この場合に発生させたくない場合は、それらを終了アクションに入れます...

ステートチャートはアクティベーションをオブジェクトのインスタンス化としてモデル化するため、コンストラクターが実行する実際の作業/アクティベーション/インスタンス化があり、状態に入ることができないほど失敗する可能性がある場合、ステートチャートは、例外をオブジェクトにマップする機能を提供することでそれをサポートします。イベント。これは、例外イベントを処理する外部状態を探して状態階層を処理する方法で処理されます。これは、コール スタック ベースの呼び出しモデルでスタックが巻き戻される方法と似ています。

これはすべて十分に文書化されています - ドキュメントを読んで試してみることをお勧めします。デストラクタを使用して「ソフトウェア リソース」をクリーンアップし、終了アクションを実行して「実際の終了アクション」を実行することをお勧めします。

例外の伝播は、ステートチャートだけでなく、すべてのイベント ドリブン環境で少し問題になることに注意してください。フォールト/エラーについて推論し、ステートチャートの設計に含めることをお勧めします。別の方法でそれらを処理できない場合にのみ、例外マッピングに頼ります。少なくともそれは私にとってはうまくいきます-ymmmv ....

于 2015-11-04T07:30:10.073 に答える