BT

Ready for InfoQ 3.0? Try the new design and let us know what you think!

3つの人気OSのカーネルを比較する

| 作者 Dingze Zhu フォローする 0 人のフォロワー , 翻訳者 吉田 英人 フォローする 0 人のフォロワー 投稿日 2010年2月14日. 推定読書時間: 10 分 |

この記事は Max Brunning 氏の発表した Solaris, BSD,Linux に対する見解から着想を得たものです。Unix 系システム同士の長所と短所を比較する,というのはよく見る話題ですが,今回の記事で取り上げるのは最新の3つのオペレーティングシステムのカーネルサブシステム – OpenSolaris,Windows Vista,そして Linux Kernel 2.6 です。その理由は簡単で,この3つがビジネス環境と開発コミュニティの両方において最も広く利用されていて,なおかつ評価の高いオペレーティングシステムであるからです。

システム評価の基準は数多くありますが,コンピュータ科学において,オペレーティングシステムの基本的な役割が不変であることは疑う余地がありません。オペレーティングシステムの目的は次の3つと考えてよいでしょう。

  • 効率性: システムリソース(特にハードウェア)の効率的な利用を可能にします。
  • 発展性: 決して変わらないただ1つのもの,それは「変わる」ということです。OS は既存のサービスに影響を与えることなく,効果的な拡張と新機能の導入を行えるように構築されなければなりません。
  • ユーザフレンドリ性: OS は毎日触れるものですから,ユーザフレンドリなインターフェースは必須です。これがなければ,上の2つの基準がどれほど良くても採用は望めないでしょう。

OS にはプロセス/スレッド管理のような機能が不可欠です。これは一定のディパッチ実行基準とメモリ管理,ファイル管理のもとで,スレッドの生成と呼び出しを行うものです。ここでは前述のサブシステムひとつひとつを比較することにします。(この記事はカーネルの比較に的を絞っているため,ユーザフレンドリ性については扱いません。)Linux と OpenSolaris には概念的に近い部分がいくつかありますが,Windows Vista のコンセプトはそれらとは大きく異なっています。

プロセスとスレッドの管理

OpenSolaris

OpenSolaris は,プロセッサリソースを柔軟に利用できるように設計された,マルチレベルのスレッドサポートを実装しています。ここでは次の4つの新しい概念が導入されています。

  • プロセス: 通常の UNIX プロセスであり,ユーザアドレス空間,スタック,プロセス管理ブロックを保持します。
  • ユーザレベルスレッド: スレッドライブラリによってプロセスのアドレス空間内で実行されるスレッドです。OS からは認識されません。ユーザレベルスレッド (user-level thread, ULT)10 はプロセス内において,ユーザが生成する実行単位です。
  • ライトウェイトプロセス: ライトウェイトプロセス (Lightweight Process,LWP) は,ユーザレベルスレッドとカーネルスレッド間のマップと見なすことができます。個々の LWP が ULT をサポートし,それを1個のカーネルスレッドにマップします。LWP はカーネルによって独立してスケジュールされ,マルチプロセッサシステムでは並列に実行される場合もあります。
  • カーネルスレッド: ひとつのシステムプロセッサ上にスケジュールされ,ディスパッチされる基本エンティティです。

ps -Lec コマンドを使用すると,図 0 に示すようにシステムプロセッサとスレッドが表示されます。

図0 Solaris 10 update 6 での出力

図1は,これら4つのエンティティの関連を示したものです。

図1 OpenSolaris スレッドモデル1

OpenSolaris の3レベルスレッド構造 (ULT,LWP,カーネルスレッド) は,OSによるスレッド管理を容易にし,アプリケーションにクリーンなインタフェースを提供する,という意図のもとに設計されています。

ユーザスレッドインターフェースは,標準的なスレッドライブラリとして使用されます。前述の ULT は LWP 上にマッピングされています。LWP は OS によって管理され,別途定義される実行ステータスを保持します。実行状態にある LWP は,1対1の対応でカーネルスレッドに結び付けられています。したがって,スレッドの実行と並行性はカーネルスレッドのレベルで管理されることになります。

またアプリケーションは,システムコールの集合体であるアプリケーションプログラムインターフェース (Application Program Interface.,API) を通じて,ハードウェアにアクセスします。API は,コールしたプロセスに代わって特権的なタスクを実行するためにカーネルサービスを起動するものです。ファイルの読み書き,デバイスへの制御コマンド発行,プロセスやスレッドの新規生成,プロセスで使用するメモリの確保などを行います。

スレッドモデルの変更は,プロセスデータの構造に影響を与えます。OpenSolaris では基本的な構造は変更されていませんが,プロセッサ状態ブロックが LWP 単位のデータブロックを格納した構造体リストに変更されています。

LWP データ構造体には次のような項目があります。

LWP 識別子 (LWP identifier)

  • この LWP のプライオリティ,すなわちそれをサポートするカーネルスレッドのプライオリティ
  • 受信可能なシグナルをカーネルに示すシグナルマスク
  • ユーザレベルレジスタの保存値 (LWP が実行していない時)
  • この LWP のカーネルスタック。システムコール引数,結果,各コールレベルのエラーコードなどが格納される
  • リソース使用とプロファイルに関するデータ
  • 対応するカーネルスレッドへのポインタ
  • プロセス構造体へのポインタ

図2 Solaris プロセス構造と通常の Unix プロセス構造の比較

Windows Vista

Vista のプロセス設計は,多種多様なOS環境のサポートを実現する,というニーズに従って決定されています。そのため,ネイティブのプロセス構造とWindows カーネルが提供するサービスは,各OSサブシステムがそれぞれのプロセス構造と機能をエミュレートできるように,比較的シンプルかつ汎用的なものとなっています。Windows プロセスの重要な特性としては,次のようなものがあります。

  • Windows プロセスは,オブジェクトとして実装されています。
  • 実行プロセスには,1ないし複数のスレッドが存在します。
  • プロセス,スレッドオブジェクトともに,組み込みの同期機能を備えています。

下の図32はプロセスと,プロセスがコントロールし,利用するリソースとの関連方法を説明しています。各プロセスにはセキュリティ・アクセス・トークンが割り当てられていますが,これをそのプロセスのプライマリ・トークンと呼びます。

図3 Windows のプロセスとスレッド

ユーザが最初にログオンするとき,Vista はそのユーザのセキュリティ ID を持ったアクセストークンを生成します。そのユーザが生成する,あるいはそのユーザの権限で動作するすべてのプロセスが,このアクセストークンのコピーを所持します。Windows はトークンを,セキュアなオブジェクトにアクセスする際のユーザ権限確認や,システムおよびセキュアなオブジェクトに対する特権機能の実行確認に使用します。またアクセストークンは,プロセス自身の属性変更の可否をコントロールするためにも使用されます。この場合,プロセスはアクセストークンに対してオープンしたハンドルを持っていません。プロセスがこのハンドルをオープンしようとすると,セキュリティシステムによってそれが許可されるかどうか,すなわちプロセスが自身の属性を変更可能かどうか,が判断されます。

他にプロセス関連のものとして,そのプロセスに現在アサインされている仮想アドレス空間を定義する,一連のブロックがあります。このデータ構造はプロセスから直接編集することはできず,仮想メモリマネージャが提供するメモリ配置サービスを利用しなければなりません。

最後に,プロセスはオブジェクトテーブルを持っていて,そこにはこのプロセスが認知している他のオブジェクトのハンドルが格納されています。このオブジェクトに含まれるスレッドごとに1つのハンドルが割り当てられます。

プロセスはファイルオブジェクトや,共有メモリのセクションを定義するセクションオブジェクトにもアクセスします。

Windows のオブジェクト指向アーキテクチャは,汎用的なプロセス機能を実現する上で効果があります。Windows Visa では2種類のプロセス関連オブジェクト,すなわちプロセスとスレッドが使用されています。プロセスは OpenSolaris と同じくユーザジョブあるいはアプリケーションに該当するエンティティであり,それ自身がメモリなどのリソースやオープンファイルを保持します。スレッドはディスパッチ可能な処理の単位で,シーケンシャルに実行されます。スレッドは中断可能であり,プロセッサを他のスレッドに移動することができます。

Windows Vista は,各プロセスに属するスレッド間の並列性によってプロセスの並列実行をサポートしています。さらに同じプロセス上のスレッドが別々のプロセッサに配置され,同時に実行される場合もあります。マルチスレッドプロセスは,複数プロセスを使用するオーバーヘッドを回避しながら並列性を実現します。同一プロセス内のスレッドは,共有するアドレス空間を通じての情報交換や,プロセスの共有リソースへのアクセスが可能です。別プロセスに属するスレッド同士は,2つのプロセスの間にセットアップされた共有メモリを通じて情報交換を行います。

オブジェクト指向マルチスレッドプロセスは,サーバアプリケーションの実装には効率的な方法です。例えば,ひとつのサーバプロセスで複数のクライアントにサービスすることが可能です。

Linux Kernel 2.6

Linux カーネル 2.6

Linux のプロセス,あるいはタスクは,task_struct というデータ構造体で表現されます。task_struct データ構造体には数多くのカテゴリの情報が格納されています。

  1. Vista や OpenSolaris とは異なり,Linux のプロセスはコンテナであり,なおかつスケジューラエンティティです。プロセスは,スレッドとしても効率的に利用できるように,アドレス空間やシステムリソースを共有できるようになっています。
  2. Vista や OpenSolaris と異なるもう1つの点は,ネットワーク機能に多くの例外があるものの,ほんとんどのサービスがカーネル内に実装されていることです。そのために Linux カーネルは,他の2つのOSに比較するとややサイズが大きくなっています。

Linux はスレッドとプロセスの区別を認識しない,というユニークなソリューションを提供しています。ユーザレベルのスレッドは,OpenSolaris のライトウェイトプロセスと同じような機構を使用して,カーネルレベルのプロセスにマップされます。グループ ID を共有する Linux のカーネルレベルプロセス群にマップされた複数のユーザレベルスレッドが,ひとつのユーザレベルプロセスを構成しています。このような構成によってこれらのプロセスは,ファイルやメモリなどのリソースを共有し,スケジューラが同一グループに属するプロセスを切り替えるときのコンテキストスイッチを回避しています。

結論

Solaris と Windows がすでに長い年月を重ねているのに対して,Linux はとても若く,まだまだこれからのOSです。また,3つのOSは明らかに,一般的なオペレーティングシステム理論に基づいて実装されています。私たちにとって最大の難題は,カーネル実装へのアクセス方法とデバッグです。私の知る限り Windows Vista にはスレッドやプロセスをトレース,デバッグする方法がないのに対して,OpenSolaris にはカーネルスレッドを検査するツールが豊富に提供されています。

次回はメモリ管理とファイルシステムについて議論する予定です。


1 Richard McDougall, Jim Mauro ,Solaris internals 2005 Pearson Education

2 Russinovich, M., and Solomon, D. Microsoft Windows Internals: Microsoft Windows Server(TM) 2003, Windows XP, and Windows 2000. Redmond, WA: Microsoft Press, 2005.

この記事に星をつける

おすすめ度
スタイル

こんにちは

コメントするには InfoQアカウントの登録 または が必要です。InfoQ に登録するとさまざまなことができます。

アカウント登録をしてInfoQをお楽しみください。

あなたの意見をお聞かせください。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする
コミュニティコメント

日本語化 by Wang Eroc

InfoQの日本語版はあまり人気がないようですね。
日本語化のミチはまだいろいろがありますね。

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

HTML: a,b,br,blockquote,i,li,pre,u,ul,p

このスレッドのメッセージについてEmailでリプライする

1 ディスカッション
BT