私は長年マルチスレッドアプリケーションを開発してきました。私はそれを熟知していると信じるまで話題がどれくらいの時間を取ることができるかは常に驚きです。今年は私にとってマルチスレッドの年になるでしょう。ここで
は私のマルチスレッドのヒントがあります:
は、マルチスレッドアプリケーションを記述しないでください。可能であれば、それから離れてください。 COM時代には、オブジェクトのスレッディングモデルを選択する必要がありました。ほとんどすべての場合、各スレッドに対して独自のメモリとオブジェクトを提供する方が良い方法でした。何も変わっていません。マルチスレッドアプリケーションは、シングルスレッドアプリケーションよりも難易度が高いものです。彼らは1995年と同じくらい難しく混乱しています。マルチスレッドを支援する上位レベルのオブジェクトはすべて、あなたが招待する論理的複雑性の増加からあなたを守ることはできません。
共有オブジェクトを分離します。マルチスレッドアプリケーションを作成する必要がある場合は、マルチスレッドの唯一の大きな課題は、同じオブジェクトに対する同時更新です。他にも小さな問題がありますが、それは大きな問題です。
あなたの周りを実行する友好的なスレッドを想像してみてください。あなたは、Webサーバー上のUpdatePerformers機能であり、あなたがコーディングしている場合: を {List.Add(パフォーマー)}
a. Imagine another thread executing on exactly the same line.
b. On the line before or after
c. Entering the function
- 想像優しいスレッド非ローカル変更した場合(List.Contains(パフォーマー)!が)オブジェクトにアクセスするとき
- 親をロックします。複雑な方法で変更される論理親がある場合、アクセスをシリアライズする最も簡単な方法は、親オブジェクトをロックすることです。 a。オーダーアイテムと数量とオプションが含まれているオーダーをお持ちの場合は、オーダーオブジェクト全体をロックします。 b。ラウンドとラウンドの詳細があるゲームをお持ちの場合は、ゲームや子供を修正する際に個々のゲームをロックしてください。
ロックを取得した後も、何か処理が必要かどうかを確認してください。
If (!Game.IsFinalized){
Lock(Game) {
If (!Game.IsFinalized)
FinalizeGame(Game)}
a。ロックが獲得された後の行では、別のスレッドがまったく同じことをするためにロックを取得したため、OFTENがロックされているため、ゲームをもう一度テストしてください。
b。または、そうすることが慣例である場合は、Called Functionをチェックして、作業を行う前にGame.IsFinalizedを確認してください。確認してください。
スレッドセーフではないものとします。スレッドの安全性は、しばしばパフォーマンスを犠牲にしたり、オブジェクトの機能や不必要な複雑さの制限を定義することが多いため、ほとんどのオブジェクトはスレッドセーフではありません。 "しかし、私は最新の最高のフレームワークを使用しています!"とは思わないでください。スレッドセーフではありません。 Entity Frameworkはスレッドセーフではありません。
.NETではConcurrentCollectionsが優れています。名前空間に「リスト」がないことがわかります。 ConcurrentListsは、マルチスレッドの番号付きリストへのランダムな挿入があいまいであり、不可能なため、より複雑です。スタック、キュー、バッグ、ディクショナリは通常大丈夫です。それに従って計画してください。
長い反復では、反復処理を行う前にリストのコピーを作成してください。コレクションを反復処理している間にコレクションが変更されている場合は、ロジックにエラーがある可能性があります...ただし、リストをロックし、浅いコピー(ToList())を作成して繰り返し処理するのがベストです。
.NETでは、タスクオブジェクトをチェックアウトする価値があります。彼らはシリアル作業をキューに入れるのに最適です。ロックは一般に問題なく、シンプルでコンパクトです。
プログラムでリソース取得の遅延がない場合、スレッド数はプロセッサの数と一致するようにしてください。 4つのコアマシンがある場合、アプリケーションで4つ以上のスレッドを実行する唯一の理由は、リソース獲得中にスレッドが待機状態に入る必要がある場合です。スレッドコンテキストスイッチは高価です。
スレッドの作成には適度なコストがかかります。オンデマンドでそれらを回転させ、それらを頻繁に破壊するならば、オーバーヘッドはかなり大きくなる可能性があります。スレッドプールを使用します。
非静的オブジェクトを誤ってロックしないでください。私はこの誤りを数回しました:Webサービス上のprivate Object _lockGameUpdate。呼び出しごとにWebサービスオブジェクトの新しいコピーが使用されるため、ファイル内のlock(_lockGameUpdate)は実質的に何もしません。ロック変数はしばしばロックするために使用するだけなので、誤った範囲にするのは簡単です。プライベートSTATICオブジェクト_lockGameUpdateはもちろん、期待通りに動作します。
試験中、試験: a。同時に始まるスレッドの束 b。ねじれたスレッドの作成 c。正確に同じパラメータを持つ別のスレッドからのダブル呼び出し。
- マルチスレッドしないでください。通常、より良い選択肢があります。
のVisual Studio
あなたはブレークポイントがすべてのスレッドのみ破壊スレッドの実行を停止するかどうかを制御することができます。条件付きブレークポイントでは、Thread = {ThreadId}を使用して、デバッグしていない他のスレッドがブレークポイントに叩かれていないことを確認できます。
別のスレッドをフリーズできます。スレッドウィンドウで行います。 「すべてのスレッドを選択する」(ctrl-a)、デバッグするスレッドの選択を解除し、「スレッドをフリーズ」をクリックしてデバッグを分離すると便利なことがよくあります。
スレッドに名前を付けます。あなたが与えた名前がスレッドウィンドウに表示されます。
良好なロギングは非常に重要です。マルチスレッドは、特に変数を評価するときに、デバッガに大きな影響を与えます。
ちょっとしたメモ。データベースの行とテーブルのロックで扱う問題は、マルチスレッドリソースの共有/ロックを進めてきた進化です。悲観的なロックや楽観的なロックのようなアイデアや、データベースが内部的にトランザクションする仕組みがあれば、それはよく理解されていれば、それ自体の中のマルチスレッドの習得の一形態です。 SQL Serverのロックと並行性の決定で見つけたすべてのアイデアとパフォーマンスのトレードオフは、異なるドメインでのマルチスレッドだけです。
マルチスレッドの難しさは、フレームワークまたは構文ベースではありません。それはLOGICをベースにしているので、データベースのような並行性解決システムは、まったく同じ論理問題を解決する必要があります。あなたがそのような経験を持っているならば、そういう考え方をしてください。
これは興味深いコミュニティウィキの記事を作るかもしれません。 –
それはあまりにも曖昧です。これまで彼が言っていたことは、Windowsに特有のものではなく、一般的なものでした。 –
これは実際の質問ではあまり曖昧です。自由な質問のためには、wikiが適切でしょう。 –