マルチスレッドアプリケーションで共有データを検索/回避するためのルール
-
03-07-2019 - |
質問
やあ、
ご存じのとおり、マルチスレッドアプリケーションの開発は難しいものです。特に、いつ、何をロックするかという点はそれほど明白ではありません。多くの場合、メソッド/クラスを見ているので、複数のスレッドで変更可能なデータを共有するかどうかを自問する必要があります。そして、コードブロック全体にわたってlock()で終わるかどうかわからないとき。
それで、私が知りたいこと:共有データを識別するためのパターン/ルールなどの提案はありますか?または、コードがスレッドセーフであることを確認する手法。
例:
- 静的メソッドはクラスフィールドを変更しないでください。 (フィールドをロックしない限り。)
- メソッドの参照型のパラメーターを「直接」渡すことはできません。常にクローンを渡します。
ところで:
Microsoft Researchは、 CHESS 。並行プログラムでハイゼンバグを見つけて再現するためのツール。これとPLINQが並行プログラムの開発を改善することを願っています。
解決
可能な限り、最初から型を不変にします。その後、クローンを作成する必要はありません。 「変更」する必要がある場合 String.Replace
などがするように、オブジェクトの内容を、メソッドが代わりに新しいオブジェクトを返すようにします。
これは基本的に関数型プログラミングスタイルであり、すばらしいです。不幸なことに(現在)不変のコレクションが.NETフレームワークに組み込まれていませんが、サードパーティのものがありますが、独自のJaredParによるものを含む。
他のヒント
クラスにデータをカプセル化すると、スレッドセーフにするときに役立ちます。データへのアクセス方法を制御できます。また、アプリケーション全体でコードを適切に同期しようとする代わりに、クラスに同期を行わせることができます。
また、ロック識別子として使用できるプライベート変数を置く場所があり、データ自体をロックの識別子として使用することを避けることができます。ロック識別子として専用のプライベート変数を使用することにより、デッドロックの原因の1つを削除できます。