1. ホーム
  2. オペレーティングシステム
  3. ソラリス

Solaris スレッドモデルの説明

2022-01-20 05:09:44

プロセスは資源管理の最小単位であり、スレッドはプログラム実行の最小単位である。オペレーティングシステムの設計において、プロセスからスレッドに進化させた主な目的は、スレッドが同じアドレス空間を共有することを利用して、対称型マルチプロセシング(SMP)をより良くサポートし、(プロセス/スレッドの)コンテキストスイッチのオーバーヘッドを削減することである。

Solarisは、UNIX系の主要ブランチであるSunが開発・リリースしている最新OSで、以下はその内部スレッドモデルの紹介と考察です。

Solaris のスレッドモデルの設計目標。

大きく分けて4つの領域があります。

①. 様々な状況下でのスレッド間作業の仕組みを記述できること

②. なるべくコストをかけないスレッドへの対応

③. シングルCPUとマルチCPUの両方の実装に対応

④. 既存のUNIXバージョンとの互換性を維持すること

Solaris のスレッドモデルの実装。

スレッドライブラリの上位カーネルはマルチプロセシングとマルチスレッドの機能を備えているため、Solarisでは、最上位にユーザースレッド、最下位に軽量プロセス(LWP)という2層構造のスレッドライブラリモデルを使用したユーザースレッド・ライブラリを多数提供しています。

LWPは実際にはカーネルスレッドであり、Solarisにおける真のスケジューリング可能な実体である。カーネルが気にするのはLWPだけであり、ユーザースレッドは気にしません。

ユーザースレッドは、ユーザースレッドとLWP間の1対1、多対多、多対1のマッピングをサポートし、ユーザースレッドとLWPプール間のマッピング関係やユーザースレッドのスケジューリングをスレッドライブラリを用いて管理しています。

Solaris には、バインドされたスレッドとバインドされていないスレッドの 2 種類のユーザースレッドがあります。結合スレッドはユーザースレッドとLWPが1対1で対応し、非結合スレッドは対応するLWPが固定されていない。その構造を図解すると以下のようになる。

上記2つを比較すると、未束縛プロセスは、ユーザースレッドがカーネルを介さずにLWPを取得するために、スレッドライブラリによってスケジューリングされる。この方法では、カーネルにとってスレッドコンテキスト切り替えはより速く、より資源効率的であり、solarisは特定のポリシーに従ってより多くのスレッドが上記を共有するためのLWPプールを提供します。

バインドされたスレッドとLWPは1対1の関係なので、リアルタイムスケジューリングはより良いですが、カーネルが参加するため、より無駄なリソースを消費します。バインドされたスレッドは、バインドされていないスレッドよりもオーバーヘッドが大きい。バインドされたスレッドはその中にあるLWPのプロパティを変更できるため、バインドされたスレッドが終了した後、LWPはキャッシュされず、新しいバインドスレッドが作成されるとOSが新しいLWPを提供します。バインドされたスレッドは、LWP内のリソース(仮想タイマーや指定スタックなど)が利用可能な場合、またはリアルタイムスケジューリングのためにスレッドがカーネルから見える必要がある場合にのみ必要とされます。

Solaris によるスレッドの制御と同期化。

カーネルは、スケジューリングタイプと優先順位に基づいてLWPをスケジューリングします。初期LWPはプロセス生成時に作成され、親プロセスのスケジューリングタイプと優先度を引き継ぎます。一般に、バインドされたユーザースレッドは、基礎となるLWPのディスパッチタイプと優先度を継承し、バインドされていないものは、親プロセスのディスパッチタイプと優先度を継承する。

Solaris カーネルは、優先順位に基づくプリエンプティブなスケジューリングメカニズムを使用しており、優先順位の高い LWP が優先順位の低い LWP よりも先に実行されます。Solaris スレッドライブラリは、LWP プールでユーザースレッドをスケジュールするために優先順位を使用して、すでに準備が整っているユーザースレッドを実行する LWP を一度に 1 つずつ選択します。LWPが無限待ちでブロックされた場合、スレッドライブラリは対応するユーザースレッドのコンテキストを保存して、そのLWPで実行する別のユーザースレッドを割り当てます。スレッドライブラリは通常、プロセスが飢餓状態に陥らないように十分な数のLWPを作成します。

Solarisは、ミューテックスロック、セマフォ、マルチリーダープロセスロック、条件変数という4つのスレッド同期化プリミティブをサポートしています。

カーネルレベルのスレッドもユーザーレベルのスレッドも、これらのプリミティブ操作を持っています。プリミティブは実行時にスレッド情報を含むデータ構造を作成し、同期オブジェクトごとにロックとアンロックの2つの操作しか行えませんが、カーネルとスレッドライブラリはアンチデッドロック機構を提供しません。

まとめると

Solarisは、マルチスレッド・マルチプロセスOSとして、スレッドの実装機構において常に業界をリードしてきました。Solaris のマルチスレッド実装機構を理解することは、オペレーティング システムがどのようにマルチスレッドを制御しているかを完全に理解するのに役立つだけでなく、マルチスレッド プログラミング スキルを向上させる方法について大きなヒントを与えてくれるでしょう。