序文
前回説明したプロセスモデルの仮定では、デフォルトのプロセスは単一の制御スレッドを持つ実行プログラムです。しかし実際には、多くの最新のオペレーティングシステムは、複数の制御スレッドを含む単一のプロセスを使用する機能を提供します。一般的に使用されるソフトウェアの多くもマルチスレッドです。たとえば、Webブラウザプログラムは、実行時に複数の制御スレッドを持つ独立したプロセスとして実装されます。これを使用すると、1つのスレッドがデータを受信し、1つのスレッドが画像を表示し、もう1つのスレッドがユーザーのキーボード入力を読み取っている可能性があります。
1つは、スレッドの概要です
スレッドとは何ですか?
スレッド: スレッドはCPUが使用する基本単位であり、スレッドID、プログラムカウンター、レジスターのセット、およびスタックで構成されます。コードセグメント、データセグメント、およびその他のオペレーティングシステムリソースを、同じプロセスに属する他のスレッドと共有します。
シングルスレッドおよびマルチスレッド:従来のヘビーウェイトプロセスには、単一の制御スレッドしかありません。プロセスに複数の制御スレッドがある場合、それは複数のタスクを同時に実行できるマルチスレッドプロセスです。
なぜスレッドを使用するのですか?
- 冒頭で述べたように、Webブラウザーなど、複数のタスクを伴う独立したプロセスの場合、通常はマルチスレッドが使用されます。
- ビジー状態のWebサーバーには、数千人のユーザーが同時にアクセスする可能性があります。従来のシングルスレッドプロセスを実行に使用する場合、一度に処理できるリクエストは1つだけであり、クライアントはリクエストを処理するために長時間待機する必要があります。Webサーバーがユーザーごとに新しいプロセスを開くことを許可されている場合、過度のオーバーヘッドが発生し、時間とリソースも消費します。
スレッドの利点は何ですか?
- 高い応答性:インタラクティブプログラムに複数のスレッドが使用されている場合、それが部分的にブロックしたり、より冗長な操作を実行したりしても、プログラムは続行できるため、ユーザーの応答性が向上します。
- リソース共有:スレッドは、デフォルトで、所有するプロセスのメモリとリソースを共有します。コードとデータの共有の利点は、アプリケーションが同じアドレス空間に複数の異なるアクティブスレッドを持つことができることです。
- 経済性:プロセスの作成に必要なメモリとリソースの割り当ては、よりコストがかかります。スレッドは所属するプロセスのリソースを共有できるため、スレッドを作成して切り替える方が経済的です。
- マルチプロセッサアーキテクチャの利用:マルチスレッドの利点の1つは、マルチプロセッサアーキテクチャを最大限に活用できるため、各プロセスを異なるプロセッサで並列に実行できることです。CPUの数に関係なく、シングルスレッドプロセスは1つのCPUでのみ実行できます。複数のCPUで複数のスレッドを使用すると、同時実行性が向上します。
2つのマルチスレッドモデル
ユーザースレッドとカーネルスレッド
スレッドサポートを提供するには、2つの異なる方法があります。
ユーザースレッド:ユーザースレッドは、カーネル管理なしでカーネルによってサポートされます。ユーザースレッド管理は、ユーザーレベルのスレッドライブラリによって実装されます。主なユーザーレベルのスレッドライブラリには、POSIX Pthread、Win32スレッド、Javaスレッドが含まれます。
カーネルスレッド:カーネルスレッドは、オペレーティングシステムによって直接サポートおよび管理されます。使用されているほとんどすべての最新のオペレーティングシステムは、カーネルスレッドをサポートしています。Windows、Linux、MacOSなど。
ユーザースレッドとカーネルスレッドの関係
ユーザースレッドが実行されると、スレッドは実行するためにカーネルスレッドに転送される必要があります。
多対1モデル
多対1モデルは、多くのユーザーレベルのスレッドを1つのカーネルスレッドにマップします。スレッド管理はスレッドライブラリによってユーザースペースで実行されるため、効率は比較的高くなります。ただし、1つのスレッドがシステム呼び出しをブロックすると、スレッド全体がブロックされます。さらに、一度に1つのスレッドのみがコアにアクセスできるため、複数のスレッドを複数のプロセッサーで並行して実行することはできません。多対1モデルは、ユーザースレッドの数を制限しません。
1対1モデル
1対1モデルは、各ユーザースレッドをカーネルスレッドにマップします。このモデルでは、1つのスレッドがブロッキングシステム呼び出しを実行するときに別のスレッドが実行を継続できるため、多対1モデルよりも優れた同時実行性が提供されます。同時に、マルチプロセッサシステムで複数のスレッドを並行して実行することもできます。このモデルの唯一の欠点は、ユーザースレッドが作成されるたびに、対応するカーネルスレッドが作成されることです。カーネルスレッドの作成のオーバーヘッドはアプリケーションのパフォーマンスに影響を与えるため、このモデルのほとんどの実装では、システムでサポートされるスレッド(ユーザースレッド)の数が制限されます。(Winodows、Linuxはこのモデルに属します)
多対多モデル
多対多モデルは、同じ数または少数のカーネルスレッドにマップされた多くのユーザースレッドを多重化します(カーネルスレッドをユーザースレッドの数より大きくすることは不可能であるため、無駄です)。多対多モデルは、ユーザースレッドの数を制限せず、同時に実行できます。
ユーザースレッドを喉が渇いた人と比較すると、カーネルスレッドはタップです。つまり、1対1は多くの人が蛇口をつかむことを意味し、2人が同時に(同時に)水を飲むことはありません。1対1は全員が蛇口を持っていることを意味し、多対多はn人を意味し、n個以下の蛇口があります。
2レベルモデル
多対多モデルと1対1モデルの組み合わせとして理解できます。複数のユーザースレッドがカーネルスレッドリソースをめぐって競合することが許可されており、一部のユーザースレッドもカーネルスレッドとバインドすることが許可されています。多対多モデルは、ユーザースレッドの数を制限せず、同時に実行できます。
3、スレッドライブラリ
スレッドライブラリを実装する2つの方法
- カーネルサポートなしでユーザースペースにライブラリを提供します(このライブラリのすべてのコードとデータ構造はユーザースペースに存在します)。ライブラリ内の関数を呼び出すと、システム呼び出しではなく、ユーザースペースでローカル関数呼び出しが発生するだけです。 。
- オペレーティングシステムで直接サポートされているカーネルレベルのライブラリを実行します(ライブラリのコードとデータ構造はカーネル空間に存在します)。ライブラリでAPI関数を呼び出すと、通常、カーネルがシステム呼び出しされます。
4、マルチスレッドの問題
システムはfork()とexec()を呼び出します
シングルスレッド制御プロセスのfork()メソッドとexec()メソッドについては前に説明しました。マルチスレッドプログラムでは、システム呼び出しfork()とexec()が変更されました。
プロセス内のスレッドがfork()を呼び出す場合、UNIXシステムでは、次の2つの処理方法が提供されます。
- 1つは、すべてのスレッドをコピーすることです
- 1つは、fork()システム呼び出しを呼び出したスレッドのみをコピーすることです。
スレッドのキャンセル
Webページが完全にロードされていない場合、ユーザーは停止ボタンをクリックしてプロセスをキャンセルできます。
一般的に使用される2つの方法:
- 非同期キャンセル:スレッドはターゲットスレッドをただちに終了します。
- キャンセルの遅延:ターゲットスレッドは、終了する必要があるかどうかを常にチェックします。これにより、ターゲットは正常に終了することができます。
信号処理
信号は何をしますか?
シグナルは、特定のイベントが発生したことをプロセスに通知するために使用されます。通知される信号のソースとイベントの理由に応じて、信号は同期的または非同期的に吸収されます。
信号に共通するもの:
- 信号は、特定のイベントの発生によって発生します。
- 生成された信号はプロセスに送信されます。
- 送信したら、信号を処理する必要があります。
信号をどのように処理しますか?
- 信号の処理がカーネルで実行されている場合、デフォルトの信号ハンドラーを使用できます。このデフォルトのアクションは、ユーザー定義のシグナルハンドラーによって上書きできます。
- ユーザー定義のシグナルハンドラーを使用します。
信号はどこに送信されますか?
- 信号が適用されるスレッドに信号を送信します。
- プロセスの各スレッドに信号を送信します。
- プロセス内の特定の固定スレッドに信号を送信します。
- プロセスのすべての信号を受信する特定のスレッドを指定します。
スレッドプール
スレッドプールがない場合、サーバーは要求を受信するたびに独立したスレッドを作成します。スレッドの頻繁な作成と破棄には時間がかかります。さらに、リクエストが増えると、無制限のスレッドがシステムリソースを使い果たします。この問題を解決するために、スレッドプールが提案されました。
スレッドプール:スレッドプールの主なアイデアは、プロセスの開始時に特定の数のスレッドを作成し、それらをプールに入れて作業を待つことです。サーバーはリクエストを受信すると、プール内のスレッドをウェイクアップし(使用可能なスレッドがある場合)、処理するリクエストをサーバーに渡します。タスクが完了すると、プールに戻り、作業を待ちます。プールに使用可能なスレッドがない場合、サーバーは空きスレッドができるまで待機します。
スレッドプールの利点:
- 既存のスレッドを使用してリクエストを処理する方が、新しいスレッドの作成を待つよりも高速です。
- スレッドプールは、いつでも使用できるスレッドの数を制限します。スレッドプール内のスレッドの数は、システムCPUの数、物理メモリのサイズ、同時クライアント要求の期待値などの要因によって決定されます。
スレッド固有のデータ
同じプロセスに属するスレッドは、プロセスデータを共有します。実際、このデータ共有にはマルチスレッドプログラミングの利点があります。ただし、場合によっては、各スレッドに、スレッド固有のデータと呼ばれる独自のデータの特定のコピーが必要になることがあります。
スケジューラのアクティブ化
多対多モデルまたは2レベルモデルを実装する多くのシステムは、ユーザーとカーネルスレッドの間に中間データ構造を設定します。このデータ構造は、軽量プロセス(LWP)と呼ばれることがよくあります。
- ためのユーザスレッド、LWPを表す仮想プロセッサアプリケーションを実行するユーザスレッドをスケジュールすることができることを。
- ためのカーネル・スレッド、各LWPは、カーネルスレッドに接続され、スレッドは、物理プロセッサ上で実行するオペレーティングシステムによってスケジュールされます。
スケジューラのアクティブ化:ユーザースレッドライブラリとカーネル間の通信を解決する方法。スケジューラアクティベーションメカニズムは、通信メカニズムであるアップコールを提供します。この通信メカニズムにより、アプリケーションは正しい数のカーネルスレッドを維持できます。アプリケーションがブロックしようとすると、イベントがアップコールをトリガーします。