並列化とマルチスレッドは、エンジニアが高速で応答性、スケーラブルなソフトウェアを構築できるように、コンピュータサイエンスのコアコンセプトです。 システムはますますマルチコアプロセッサと分散アーキテクチャに依存しているため、これらのトピックをマスターすることは、パフォーマンスボトルネックに取り組むこと、データの完全性を確保し、効率的なリソース利用を達成するための不可欠となっています。 この記事では、主要な原則、一般的なインタビュー質問、およびすべてのエンジニアが同時およびマルチスレッドシステムを扱うときに知っておくべき実用的な戦略について説明します。

通貨とは?

並列化は、時間期間を重ねる際に複数のタスクを処理するためのシステムの機能を指します。必ずしも、タスクが同じ正確なインスタンス()で実行されているという意味ではありません。並列)ではなく、システムが実行を中断することによって複数のタスクで進行をすることができることを意味します。並列は、特にI/O-boundまたはインタラクティブなアプリケーションで、スループットと応答性を向上させます。

いくつかのメカニズムでコンカレンシーを達成することができます。

  • []マルチスレッド] - 複数のスレッドを単一プロセス内で。
  • []マルチプロセッシング - 別のCPUコアで実行できる複数のプロセス。
  • [非同期プログラミング[]] – 単一スレッドが複数のタスクを処理することを可能にする非ブロック操作(例えば、コールバック、先物、または非同期/待ち)。

現代のオペレーティングシステムとランタイムは、スレッド、プロセス、イベントループなどの通貨の原始性を提供します。 これらのアプローチ間のトレードオフを理解することは、エンジニアのための基礎的なスキルです。

通貨モデルへのより深いダイビングについては、【]】の口コミを読んでください。

多面的な理解

マルチスレッドは、同じメモリ空間とリソースを共有する複数のスレッドをスポーンする単一プロセスが並行するコンポレーションの特定の実装です。各スレッドには独自のコールスタックとプログラムカウンターがありますが、プロセス内のすべてのスレッドは共有ヒープメモリに読み書きできます。この共有アクセスは、両方の強さと脆弱性です。

多読化の主な側面は、次のとおりです。

  • []3つの作成と管理[] - スレッドは、オーバーヘッドを避けるために、明示的に作成またはスレッドプールによって管理することができます。
  • []3つのライフサイクル] - 新規、実行可能、ブロック、待機、待機、待機、終了などの状態。
  • []コンテキスト切り替え] - スレッド間のOSスイッチは、いくつかのオーバーヘッドを引き起こします。
  • []共有リソース - データ構造、ファイル、および接続は同時アクセスから保護する必要があります。

マルチスレッドは、特に、並列化できるCPU-boundタスク(画像処理、科学シミュレーション)や、他の作業(例えば、Webサーバー)で作業を継続しながら、スレッドがデータを待つことができるI/O-boundタスクのために特に便利です。ただし、誤った使用は、レース条件、デッドロック、および矛盾状態などの微妙なバグにつながることができます。

Java のマルチスレッドに関する実用的なガイダンスでは、 Oracle Java の並列チュートリアル は優れたリソースです。

並列とマルチスレッド間の重要な違い

交換可能に使われることが多いですが、通貨とマルチスレッドは異なる概念です。下の表は、主な違い(意味リストを使用して):

  • [Concurrency]は、システムの特性です。複数のタスクを同時に処理できます。マルチスレッド、マルチプロセス、または非同期技術によって達成することができます。
  • マルチスレッド]は、単一プロセス内で複数のスレッドを使用して、対立性を実現するためのプログラミング技術です。
  • 並列化は、複数のタスクを一度に処理するプログラムをstructuring に焦点を合わせ、マルチスレッドは低レベルの実装の詳細です。
  • 複数の読み物は共有メモリを含みます。これは、レース条件やメモリの一貫性の問題などの課題を紹介します。より高いレベルでの並列(例えば、俳優モデル)は、共有状態を避けることができます。
  • スレッドを使わずにシステムが同時並行できます(例:単一スレッドでイベントを駆動するプログラミング)。
  • 真の並列性は複数のCPUコアを必要としますが、時間のスライスを通して単一コアで対立性をシミュレートすることができます。

エンジニアの一般的な並列性とマルチスレッドの質問

エンジニアは、同時プログラムやマルチスレッドコードのデバッグを理由として、その能力についてしばしばテストされます。 以下は、詳細な説明でいくつかの拡張された質問です。

1. レース条件の予防は?

レース条件は、共有データにアクセスする2つ以上のスレッドが同時に発生し、最終結果は、実行のタイミングによって異なります。 防止戦略は次のとおりです。

  • []Mutexes(ロック)[ - 1つのスレッドのみが重要なセクションを一度に入力できるようにします。
  • ]Semaphores] - リソースの有限プールへのアクセスを制御する。
  • 原子操作] - CPUレベルの指示(例、比較とスワップ)を簡単な更新に使用します。
  • ]読み書きロック - 同時読みを許可しますが、排他的な書き込み。
  • [] オブジェクト[]] - 変更できないデータを共有し、レースを完全に排除します。
  • [] スレッドローカルストレージ[] - それぞれにデータをコピーします。

機構の選択は、共有リソースと必要な性能特性の性質に依存します。

2.デッドロックとは何か、どのように回避できるのか?

Deadlockは、別のスレッドによって保持されるリソースを2つ以上スレッドがそれぞれ待機している状況で、すべて無期限にストールする状態です。デッドロックの古典的な条件は次のとおりです。相互の排除、保持および待機、予防措置、および円形待ち。回避技術は次のとおりです。

  • [] リソース階層[をリソースにグローバルオーダーを割り当て、その順序でロックを取得するスレッドが必要です。
  • []タイムアウト] - 一定期間後にロックを解放し、再試行します。
  • [デッドロック検出] - デッドロックが起こるようにするが、それらを壊れるメカニズム(例えば、スレッドを終端に)を持っている。
  • ロックフリープログラミング - アトミック操作を使用して、ロックを完全に回避します。

エンジニアは、ロック取得パターンを慎重に設計し、潜在的なデッドロックをキャッチするために、重い通貨の下でテストする必要があります。

3. 糸の同期の衝撃性能はいかにしますか。

同期はデータの一貫性を確保するが、オーバーヘッドを導入する。主要なパフォーマンスのトレードオフは次のとおりです。

  • []Contention] - 多くのスレッドが同じロックを買収しようとすると、実行をシリアライズし、並列性を低下させます。
  • []コンテキスト切り替え] - ロックをブロックするスレッドは、OSがコンテキストを切り替える力で、高価です。
  • [キャッシュコヒーレンシー] - 可変的なデータ共有は、CPUキャッシュを無効化し、メモリトラフィックを増加させます。
  • 粒度] – 粗挽きロック(例えば、単一のグローバルロック)は、正しさを簡素化し、逆転を制限する; 微結晶ロック(例えば、パーエレメントロック)は並列を改善しますが、複雑さとリスクのデッドロックを増加させる。

ロックストライプ、読み取りライトロック、および同時データ構造などの近代的な戦略(例:)は、安全と速度のバランスをとります。

4. Java/C# の キーワードの説明。 どのような問題が解決しますか?

[ キーワードは、変数の値を常に読み、書きしてメインメモリに書き出し、スレッドローカルキャッシュを防止することを確認します。 可視性の問題を解決します。 揮発変数への書き込みは、すべてのスレッドに即座に表示されます。 しかし、 ] は []]] は、化合物の動作に対する妥協性を保証します(例えば、 )])。 は、 状態のフラグまたは実行に使用されます。

5. 糸プールとは何か、いつ使うべきか?

スレッドプールは、タスクを実行するために再利用できる事前作成スレッドのコレクションです。 利点には、スレッドの作成と涙のオーバーヘッドを削減し、応答時間を改善し、リソースの使用量を制御します。 スレッドプールは、HTTPリクエストをサービングするなど、多くの短命またはI/O-boundタスクを処理するのに最適です。 一般的な実装には、Javaおよびの]が含まれています。

注意は、プールを適切にサイズするために取られなければなりません。CPUコアを過小数スレッドにすぎず、過度のコンテキスト切り替えやメモリ消費を引き起こします。

6. Amdahlの法則とは、なぜマルチスレッドのパフォーマンスに問題がありますか?

Amdahlの法則は、複数のプロセッサーを使用してプログラムのスピードアップがプログラムのシーケンシャル部分によって制限されるという状態です。数学的に:スピードアップ = 1 /(1 - P) + P / N)[[]、Pは並列可能な分数であり、Nはプロセッサー数です。例えば、コードの10%がシーケンシャルを実行する必要がある場合は、コアと最大速度は、シリアルアルゴリズムを10gn(設計)、およびnは、設計を制限します。

エンジニアがコンカレンシーで働くベストプラクティス

堅牢で高性能な同時並行コードを書くには、次のガイドラインに従ってください。

  • より高いレベルの抽象化[を予報する - 生糸管理ではなく、行列サービス、および同時収集を使用する。
  • [] 初期化データfirst[] – 共有ミュータブルな状態を避けます。 不変なオブジェクトまたはコピーオンライトパターンを使用してください。
  • []ロックスコープを最小化 - 重要な操作を実行する最短時間だけロックを保持します。
  • [] 単純な操作のためのロックフリーアルゴリズムを使用 - 原子変数と比較とスワップは、ロックよりも効率的であることができます。
  • 実際の通貨でテスト - レース、デッドロック、およびデータ破損を検出するために、ストレステストツールとスレッドのサニタイザーを使用します。
  • [文書同期契約[ - 明示的に、変数がスレッドセーフであり、ロックが保護される状態。
  • [コンサイダーの代替] – 俳優モデル(例えば、Akka)、メッセージの渡、または共同した状態を減らすための反応ストリームを調べます。

基底プラットフォーム(Java Memory Model、POSIX スレッド、または Python GIL など)の徹底的な理解は、オッズ動作をデバッグするために不可欠です。

コンテンツ

並列化とマルチスレッドは単なる理論的概念ではありません。それらは、ソフトウェアの品質に直接影響を及ぼす実用的なツールです。レース条件を識別し、デッドロックを防止し、リソースのセパニオンを管理するために学習することで、エンジニアは迅速かつ信頼性のあるシステムを設計します。この記事で強調されたインタビューの質問は、より深い研究のための開始点を表しています。マルチコアと分散コンピューティングが進化し続けるにつれて、同時実行の理由は、すべてのエンジニアにとって重要なスキルを維持します。

更に読むには、 ] の GeeksforGeeks concurrency article] の包括的なガイドと の Java のバエルダン の並列を調べます。