GNU/Linux >> Linux の 問題 >  >> Linux

Linux スレッドの紹介 – パート I

実行スレッドは、多くの場合、スケジューラが処理する最小の処理単位と見なされます。

プロセスは、非同期で実行される複数の実行スレッドを持つことができます。

この非同期実行により、特定の作業またはサービスを個別に処理する各スレッドの機能がもたらされます。したがって、プロセス内で実行される複数のスレッドは、全体としてプロセスの完全な機能を構成するサービスを処理します。

この記事では、スレッドの基礎に触れ、実践を学ぶために必要な基本的な理解を構築します。 Linux スレッドの側面。

Linux スレッド シリーズ:パート 1 (この記事)、パート 2、パート 3.

スレッドが必要な理由

では、なぜプロセスに複数のスレッドが必要なのですか??すべての状況で、メイン スレッドが 1 つしかない (既定の) プロセスを使用できないのはなぜですか。

これに答えるために、例を考えてみましょう:

リアルタイムの入力を受け取り、各入力に対応して特定の出力を生成する必要があるプロセスがあるとします。ここで、プロセスがマルチスレッド化されていない場合、つまりプロセスに複数のスレッドが含まれていない場合、プロセス内の処理全体が同期になります。これは、プロセスが入力を受け取り、それを処理して出力を生成することを意味します。

上記の設計の制限は、プロセスが前の処理を完了するまで入力を受け入れることができず、入力の処理に予想よりも時間がかかる場合、それ以上の入力の受け入れが保留になることです。

上記の制限の影響を検討するために、上記の一般的な例を、入力接続を受け入れることができるソケット サーバー プロセスにマッピングすると、それらを処理し、ソケット クライアントに出力を提供します。現在、入力の処理中にサーバー プロセスに予想以上の時間がかかり、その間に別の入力 (接続要求) がソケット サーバーに送信された場合、サーバー プロセスは新しい入力接続を受け入れることができません。古い入力接続を処理しています。これにより、ソケット クライアントで望ましくない接続タイムアウトが発生する可能性があります。

これは、実行の同期モデルをどこにでも適用できるわけではないことを示しているため、スレッドを使用して実装される非同期実行モデルの必要性が感じられました。

スレッドとプロセスの違い

以下は、スレッドとプロセスの主な違いの一部です:

  • プロセスはアドレス空間を共有しませんが、同じプロセスで実行されるスレッドはアドレス空間を共有します。
  • 上記の点から、プロセスは互いに独立して実行され、プロセス間の同期はカーネルによってのみ処理されるのに対し、スレッドの同期はスレッドが実行されているプロセスによって処理される必要があることは明らかです
  • スレッド間のコンテキストの切り替えは、プロセス間のコンテキストの切り替えに比べて高速です
  • 2 つのプロセス間の相互作用は、標準のプロセス間通信によってのみ実現されますが、同じプロセスで実行されるスレッドは、メモリやテキスト セグメントなどのほとんどのリソースを共有するため、簡単に通信できます

ユーザー スレッドとカーネル スレッド

スレッドは、カーネル空間だけでなくユーザー空間にも存在できます。

ユーザー スペース スレッドは、ユーザー空間のスレッド ライブラリを使用して作成、制御、および破棄されます。これらのスレッドはカーネルに認識されていないため、カーネルはそれらの処理に関与していません。これらのスレッドは協調マルチタスキングに従います。スレッドは独自の要求で CPU を解放します。つまり、スケジューラはスレッドを横取りできません。ユーザー空間スレッドの利点は、2 つのスレッド間の切り替えにあまりオーバーヘッドがかからず、マイナス面にある間は一般に非常に高速であることです。これは、これらのスレッドが協調マルチタスクに従うため、1 つのスレッドがブロックされるとプロセス全体がブロックされるためです。

カーネル スペース スレッドはカーネルによって作成、制御、破棄されます。ユーザー空間に存在するすべてのスレッドには、対応するカーネル スレッドがあります。これらのスレッドはカーネルによって管理されるため、プリエンプティブ マルチタスキングに従います。この場合、スケジューラは、実行の準備ができている優先度の高いスレッドで実行中のスレッドをプリエンプトできます。カーネル スレッドの主な利点は、カーネル スレッドがプリエンプティブ スケジューリングに従うため、スレッドの 1 つがブロックされても、プロセス全体がブロックされないことです。一方、マイナス面として、ユーザー空間スレッドと比較してコンテキスト スイッチはそれほど高速ではありません。

Linux について言えば、カーネル スレッドは、ユーザー空間のスレッドよりも優れていると見なされる程度に最適化されており、主要な要件が協調的なマルチタスクである場合を除いて、ほとんどすべてのシナリオで使用されます。

スレッドの問題

スレッドの使用中に発生するいくつかの大きな問題があります:

  • 多くのオペレーティング システムは、スレッドをプロセスとして実装せず、スレッドを親プロセスの一部として認識します。この場合、スレッドが fork() を呼び出すとどうなるか、さらに悪いことに、スレッドが新しいバイナリを実行するとどうなるでしょうか??これらのシナリオは危険な結果をもたらす可能性があります。たとえば、後者の問題では、親プロセス全体が新しく実行されたバイナリのアドレス空間に置き換えられる可能性があります。これはまったく望ましくありません。 POSIX 準拠の Linux では、fork() を呼び出すと、fork() 関数を呼び出したスレッドのみが複製されますが、いずれかのスレッドからの exec は親プロセスのすべてのスレッドを停止します。
  • 発生する可能性のあるもう 1 つの問題は、同時実行の問題です。スレッドはすべてのセグメント (スタック セグメントを除く) を共有し、スケジューラによって任意の段階でプリエンプトされる可能性があるため、1 つのスレッドのプリエンプションによって一貫性のない状態のままになる可能性があるグローバル変数またはデータ構造よりも、次の優先度の高いスレッドが重大な問題を引き起こす可能性があります。スレッドは同じ関数を実行し、同じ変数またはデータ構造を使用します。

上記の問題 1 については、これは設計上の問題であり、アプリケーションの設計は、この種の問題が発生するのを最小限に抑える方法で行う必要があるとしか言えません。

上記の問題 2 については、ロック メカニズムを使用して、プログラマーは関数内のコードのチャンクをロックできるため、コンテキスト スイッチが発生した場合でも (関数のグローバル変数とデータ構造が矛盾した状態にある場合)、次のスレッドも関数内のロックされたコード ブロックが前のスレッド (またはそれを取得したスレッド) によってロック解除されるまで、同じコードを実行します。


Linux
  1. Linux シグナルの基礎 – パート I

  2. Linux IP ルーティングの基礎の紹介 (パート 1)

  3. Linux の CreateProcess?

  1. Linuxでゾンビプロセスを強制終了する方法

  2. Linux でのデーモンの作成

  3. Linux:サービスへの処理

  1. KaliLinuxでのNmapの概要

  2. Linux の起動プロセス

  3. Linux のプロセスあたりの最大スレッド数は?