7

私たちのコードベースは数年前のもので、元の開発者は全員いなくなっています。非常に多くのスレッドを使用しますが、明らかな設計や共通のアーキテクチャ原則はありません。すべての開発者は独自のマルチスレッド プログラミング スタイルを持っていたため、キューを使用して相互に通信するスレッド、ミューテックスを使用してデータをロックするスレッド、セマフォを使用してロックするスレッド、プロセス内通信にオペレーティング システムの IPC メカニズムを使用するスレッドなどがあります。設計ドキュメントはなく、コメントはまばらです。コードをリファクタリングしたり、新しい機能を追加しようとすると、デッドロックやその他の問題が発生するようです。

では、スレッド間のすべての相互作用を分析して文書化するのに役立つツールや手法を知っている人はいますか? FWIW、コードベースは Linux の C++ ですが、他の環境用のツールについて知りたいです。


アップデート

これまでに寄せられた回答には感謝していますが、本質的に「ログ メッセージを追加し、何が起こっているかを把握し、修正する」というアドバイスよりも、より洗練された、または体系的なものを期待していました。シングルスレッド プログラムの制御フローを分析および文書化するためのツールは数多くあります。マルチスレッドプログラムで利用できるものはありませんか?


マルチスレッド アプリケーションのデバッグも参照してください。

4

7 に答える 7

6

Intel のVTuneとそのスレッド プロファイリング ツールのコピーに投資してください。スレッドの動作のシステム レベルとソース レベルの両方のビューが表示されます。確かに自動文書化するつもりはありませんが、少なくともさまざまな状況で何が起こっているかを視覚化するのに役立つはずです.

ダウンロードできる試用版があると思いますので、試してみる価値があるかもしれません。私は Windows 版しか使っていませんが、VTune の Web ページを見ると Linux 版もあります。

于 2008-08-21T18:38:14.323 に答える
4

出発点として、アプリケーション内の重要なポイントにトレース ログ メッセージを追加したくなるでしょう。これにより、スレッドを監視する行為がスレッドの動作を変更する危険を冒さずに、スレッドがどのように相互作用しているかを分析できます (段階的なデバッグの場合のように)。私の経験は .NET プラットフォームであり、お気に入りのログ ツールは log4net です。これは、無料であり、広範な構成オプションがあり、ログの実装方法に賢明であれば、アプリケーションのパフォーマンスを著しく妨げないためです。または、System.Diagnostics 名前空間に .NET の組み込み Debug (または Trace) クラスがあります。

于 2008-08-13T15:33:28.900 に答える
3

問題を引き起こす可能性が最も高い共有メモリ ロック (ミューテックスとセマフォ) に最初に注目します。ロックによって保護されている状態を確認し、複数のロックによって保護されている状態を特定します。これにより、潜在的な競合の感覚が得られます。ロックを保持しているコードがメソッドを呼び出す状況を見てください (仮想メソッドを忘れないでください)。可能であれば、これらの呼び出しを排除するようにしてください (ロックが保持される時間を短縮することによって)。

保持されているミューテックスのリストと、それらが保護する状態の大まかなアイデアが与えられたら、ロック順序を割り当てます (つまり、ミューテックス A は常にミューテックス B よりも前に取得する必要があります)。コードでこれを強制するようにしてください。

同時実行性に悪影響がなければ、複数のロックを 1 つに結合できるかどうかを確認してください。たとえば、ミューテックス A と B にデッドロックが発生している可能性があり、順序付けスキームを簡単に実行できない場合は、最初にそれらを 1 つのロックに結合します。

簡単ではありませんが、同時実行性を犠牲にしてコードを単純化して、問題を処理できるようにします。

于 2008-08-13T20:41:07.983 に答える
2

これは、自動化ツールにとって非常に難しい問題です。コードをチェックするモデルを調べたい場合があります。魔法のような結果を期待しないでください。モデル チェッカーは、効果的にチェックできるコードの量とスレッドの数が非常に限られています。

あなたに役立つかもしれないツールはCHESSです(残念ながら、これは Windows のみです)。BLASTもかなり強力なツールですが、使い方が非常に難しく、C++ を処理できない場合があります。ウィキペディアにはStEAMもリストされていますが、これは聞いたことはありませんが、うまくいくようです。

StEAM は C++ 用のモデル チェッカーです。デッドロック、セグメンテーション違反、範囲外の変数、非終了ループを検出します。

あるいは、コードを少数の明確に定義された (そしてできれば高レベルの) 同期スキームに収束させようとすることは、おそらく大いに役立つでしょう。ロック、セマフォ、およびモニターを同じコード ベースに混在させると、問題が発生します。

于 2008-08-21T19:11:07.350 に答える
1

ここで UML が役に立ちませんか?

コードベースをUMLにリバース エンジニアリングすると、クラス間の関係を示すクラス図を描くことができるはずです。メソッドがスレッド エントリ ポイントであるクラスから始めて、どのスレッドがどのクラスを使用しているかを確認できます。Rational Roseでの私の経験に基づくと、これはドラッグ アンド ドロップを使用して実現できます。追加されたクラスと以前のクラスの間に関係がない場合、追加されたクラスは、ダイアグラムを開始したメソッドで開始されたスレッドによって直接使用されません。これにより、各スレッドの役割に関するヒントが得られるはずです。

これにより、共有されている「データ オブジェクト」とスレッド固有のオブジェクトも表示されます。

大きなクラス図を描いてすべての「データ オブジェクト」を削除すると、その図を雲としてレイアウトできるはずです。各雲はスレッドまたはスレッドのグループです。最悪。

これでパズルの一部しか解けませんが、役に立つかもしれません。あなたのコードベースが汚すぎたり、「手続き的」すぎたりしないことを願っています。

于 2008-09-26T14:25:16.313 に答える
1

Java では、FindBugs (静的バイトコード分析用) などの選択肢があり、特定の種類の矛盾した同期を検出したり、Coverity、JProbe、OptimizeIt などの企業が提供する多くの動的スレッド アナライザーを使用したりできます。

于 2008-09-22T02:19:57.723 に答える
1

log4net または同様のツールを使用する際に留意すべきことの 1 つは、アプリケーションのタイミングが変更され、多くの場合、根本的な競合状態が隠される可能性があるということです。デバッグするコードが不十分で、ロギングを導入しましたが、これにより実際に競合状態とデッドロックが解消されました (または、その頻度が大幅に減少しました)。

于 2008-08-13T20:27:23.190 に答える