2009-07-08 8 views
0

マルチスレッドアプリケーションを開発している誰かに提供するヒントは何ですか?私は考えることができるマルチスレッド(Windowsプラットフォーム)のヒント

唯一のものです:それは避けられる

  • は、同じデータ構造への書き込みを複数のスレッドを持っていません。

  • これは避けることはできませんが、最終スレッドが完了するまで待機するようにクリティカルセクションを用意してください。

  • 定数以外のグローバル変数は使用しないでください。

  • リソースが終了するとすぐにスレッドがリソースを解放することを確認します。

他に何か考えてもらえますか?

+1

これは興味深いコミュニティウィキの記事を作るかもしれません。 –

+0

それはあまりにも曖昧です。これまで彼が言っていたことは、Windowsに特有のものではなく、一般的なものでした。 –

+3

これは実際の質問ではあまり曖昧です。自由な質問のためには、wikiが適切でしょう。 –

答えて

1

マルチスレッドは、非常に複雑な問題である - 私の最大のアドバイスはに次のようになります - 多くの場合、マルチスレッドの複雑さが過小評価されている任意の選択肢があるかどうか考えてみましょう

  1. 初めてスレッドを作成する場合は、小さなスレッドから始めて簡単に実行してください。実際に理解する時間をとりましょう正確にはスレッド同士が相互作用する方法 - 同じスレッドを同時に実行する方法、どのスレッドがお互いに待っているのかを知ることができます。言っ

、私は正直に何もマルチスレッディングについて根本的に困難が存在しないことを信じて、それはプログラマの多くは、そう、彼らは、マルチスレッド環境では有効でない仮定を行うことシングルスレッドプログラミングに使用されているだけのことです。あなたがマルチスレッドに慣れていない場合は、このような理由で極度の注意を払ってアプローチする必要があります。

+1

私はあなたのアイテム1についての混乱した感情を持っています...私は人々がマルチスレッドは、マルチスレッドが必要であるという前提が生じますが、マルチスレッドはコアコンセプトです。 「キャンセルボタンをクリックできません! 「私たちのサーバがxメッセージを受け取ると、いくつかを無視し始める」というのは、マルチスレッドの必要性に気づいていないという一般的な症状です。それは、いつ、いつ、いつではないかを知る必要があるもう一つのケースです – STW

+0

ええ、私はそれに同意します - 更新しました。 – Justin

-1

行レベルのロックを使用します。

TRANSACTION_READ_COMMITTED分離レベルを使用します。

インデックスを使用できないクエリは避けてください。テーブル内のすべての行をロックする必要があり(非常に短時間であれば)、更新がブロックされる可能性があります。

Multithreading: Programming Tips

0

複数のオブジェクトをロックする場合、常に同じ順序でロックしてみてください。これによりデッドロックへの被害を最小限に抑えることができます。質問の広さ(または曖昧さ)を考えると

2

は、私はあなたがジョーダフィー、ISBNすることにより、Windows上で並行プログラミングのコピーを拾うお勧め:978-0-321-43482-1

0

基本アドバイス:
設計と計画が
は-spend正確に実行すべきか、優先順位を特定し、何が共有リソースを制御するための効率的な方法-use非同期モード
リソース制御
で行うことができますいくつかの時間の理解は、クリティカルセクションがあります前スレッドのスレッド
-reuseを再作成この
避け効率と性能をもたらしますため
優先順位付け活動
OD法-log記録は、この目的のために特定のスレッドによって行われなければならないので、コアはしていません無駄な時間

0

私は長年マルチスレッドアプリケーションを開発してきました。私はそれを熟知していると信じるまで話題がどれくらいの時間を取ることができるかは常に驚きです。今年は私にとってマルチスレッドの年になるでしょう。ここで

は私のマルチスレッドのヒントがあります:

  1. は、マルチスレッドアプリケーションを記述しないでください。可能であれば、それから離れてください。 COM時代には、オブジェクトのスレッディングモデルを選択する必要がありました。ほとんどすべての場合、各スレッドに対して独自のメモリとオブジェクトを提供する方が良い方法でした。何も変わっていません。マルチスレッドアプリケーションは、シングルスレッドアプリケーションよりも難易度が高いものです。彼らは1995年と同じくらい難しく混乱しています。マルチスレッドを支援する上位レベルのオブジェクトはすべて、あなたが招待する論理的複雑性の増加からあなたを守ることはできません。

  2. 共有オブジェクトを分離します。マルチスレッドアプリケーションを作成する必要がある場合は、マルチスレッドの唯一の大きな課題は、同じオブジェクトに対する同時更新です。他にも小さな問題がありますが、それは大きな問題です。

  3. あなたの周りを実行する友好的なスレッドを想像してみてください。あなたは、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 
    
  4. 想像優しいスレッド非ローカル変更した場合(List.Contains(パフォーマー)!が)オブジェクトにアクセスするとき
  5. 親をロックします。複雑な方法で変更される論理親がある場合、アクセスをシリアライズする最も簡単な方法は、親オブジェクトをロックすることです。 a。オーダーアイテムと数量とオプションが含まれているオーダーをお持ちの場合は、オーダーオブジェクト全体をロックします。 b。ラウンドとラウンドの詳細があるゲームをお持ちの場合は、ゲームや子供を修正する際に個々のゲームをロックしてください。
  6. ロックを取得した後も、何か処理が必要かどうかを確認してください。

    If (!Game.IsFinalized){ 
        Lock(Game) { 
         If (!Game.IsFinalized) 
         FinalizeGame(Game)} 
    

    a。ロックが獲得された後の行では、別のスレッドがまったく同じことをするためにロックを取得したため、OFTENがロックされているため、ゲームをもう一度テストしてください。

    b。または、そうすることが慣例である場合は、Called Functionをチェックして、作業を行う前にGame.IsFinalizedを確認してください。確認してください。

  7. スレッドセーフではないものとします。スレッドの安全性は、しばしばパフォーマンスを犠牲にしたり、オブジェクトの機能や不必要な複雑さの制限を定義することが多いため、ほとんどのオブジェクトはスレッドセーフではありません。 "しかし、私は最新の最高のフレームワークを使用しています!"とは思わないでください。スレッドセーフではありません。 Entity Frameworkはスレッドセーフではありません。

  8. .NETではConcurrentCollectionsが優れています。名前空間に「リスト」がないことがわかります。 ConcurrentListsは、マルチスレッドの番号付きリストへのランダムな挿入があいまいであり、不可能なため、より複雑です。スタック、キュー、バッグ、ディクショナリは通常大丈夫です。それに従って計画してください。

  9. 長い反復では、反復処理を行う前にリストのコピーを作成してください。コレクションを反復処理している間にコレクションが変更されている場合は、ロジックにエラーがある可能性があります...ただし、リストをロックし、浅いコピー(ToList())を作成して繰り返し処理するのがベストです。

  10. .NETでは、タスクオブジェクトをチェックアウトする価値があります。彼らはシリアル作業をキューに入れるのに最適です。ロックは一般に問題なく、シンプルでコンパクトです。

  11. プログラムでリソース取得の遅延がない場合、スレッド数はプロセッサの数と一致するようにしてください。 4つのコアマシンがある場合、アプリケーションで4つ以上のスレッドを実行する唯一の理由は、リソース獲得中にスレッドが待機状態に入る必要がある場合です。スレッドコンテキストスイッチは高価です。

  12. スレッドの作成には適度なコストがかかります。オンデマンドでそれらを回転させ、それらを頻繁に破壊するならば、オーバーヘッドはかなり大きくなる可能性があります。スレッドプールを使用します。

  13. 非静的オブジェクトを誤ってロックしないでください。私はこの誤りを数回しました:Webサービス上のprivate Object _lockGameUpdate。呼び出しごとにWebサービスオブジェクトの新しいコピーが使用されるため、ファイル内のlock(_lockGameUpdate)は実質的に何もしません。ロック変数はしばしばロックするために使用するだけなので、誤った範囲にするのは簡単です。プライベートSTATICオブジェクト_lockGameUpdateはもちろん、期待通りに動作します。

  14. 試験中、試験: a。同時に始まるスレッドの束 b。ねじれたスレッドの作成 c。正確に同じパラメータを持つ別のスレッドからのダブル呼び出し。

  15. マルチスレッドしないでください。通常、より良い選択肢があります。

のVisual Studio

あなたはブレークポイントがすべてのスレッドのみ破壊スレッドの実行を停止するかどうかを制御することができます。条件付きブレークポイントでは、Thread = {ThreadId}を使用して、デバッグしていない他のスレッドがブレークポイントに叩かれていないことを確認できます。

別のスレッドをフリーズできます。スレッドウィンドウで行います。 「すべてのスレッドを選択する」(ctrl-a)、デバッグするスレッドの選択を解除し、「スレッドをフリーズ」をクリックしてデバッグを分離すると便利なことがよくあります。

スレッドに名前を付けます。あなたが与えた名前がスレッドウィンドウに表示されます。

良好なロギングは非常に重要です。マルチスレッドは、特に変数を評価するときに、デバッガに大きな影響を与えます。

ちょっとしたメモ。データベースの行とテーブルのロックで扱う問題は、マルチスレッドリソースの共有/ロックを進めてきた進化です。悲観的なロックや楽観的なロックのようなアイデアや、データベースが内部的にトランザクションする仕組みがあれば、それはよく理解されていれば、それ自体の中のマルチスレッドの習得の一形態です。 SQL Serverのロックと並行性の決定で見つけたすべてのアイデアとパフォーマンスのトレードオフは、異なるドメインでのマルチスレッドだけです。

マルチスレッドの難しさは、フレームワークまたは構文ベースではありません。それはLOGICをベースにしているので、データベースのような並行性解決システムは、まったく同じ論理問題を解決する必要があります。あなたがそのような経験を持っているならば、そういう考え方をしてください。

関連する問題