| 日本−日本語 |
|
|
|
![]() |
HP-UX リファレンス: セクション 3 : ライブラリ (N~Z) > ppthread(3T)pthread ライブラリHP-UX 11i Version 2: September 2004 |
|
名称pthread ― POSIX.1c でのスレッドの概要 説明HP で開発した POSIX.1c のライブラリにより、アプリケーションおよびマルチプロセッサプラットフォームの並列処理を利用できるプロセスの作成が可能になります。pthread ライブラリ libpthread は、90 以上の標準化されたインタフェースで構成され、並列のアプリケーションの開発とそれらの処理をプロセス内またはプロセス間で同期させることが可能です。このマンページでは、libpthread の用語およびスレッドを使用するプログラムのコンパイルおよびリンクの方法を含む概要を説明します。 コンパイルの概要マルチスレッドのアプリケーションでは、コンパイル時に適切な POSIX リビジョンレベル (199506) を定義して、-lpthread により pthread ライブラリにリンクしなければなりません。例: cc -D_POSIX_C_SOURCE=199506L -o myapp myapp.c -lpthread すべてのプログラムソースには、ヘッダーファイル <pthread.h> が含まれていなければなりません。 注記: ("-Aa" を指定して) ANSI コンパイルを明示的に指定する場合、POSIX リビジョンレベルを定義すると、プログラムは POSIX ネームスペース内のインタフェースだけを使用します。より大きな X/Open ネームスペース内のインタフェースが呼び出される場合には、-D_POSIX_C_SOURCE=199506L の他に、-D_XOPEN_SOURCE_EXTENDED または -D_HPUX_SOURCE のいずれかのコンパイラオプションの指定が必要です。-Ae を指定して (あるいは "-A" を指定せずに) コンパイルすると、-D_HPUX_SOURCE が暗黙的に指定されます。 注記: 一部のドキュメンテーションでは、コンパイルに -D_REENTRANT を使用するようにお薦めしています。これも正しく機能しますが、旧形式であると考えられます。 スレッドの概要スレッド は、プロセス内の独立した制御の流れであり、コンテキスト (レジスタセットおよびプログラムカウンターを含む) および一連の実行命令で構成されます。 すべてのプロセスは、最低でも 1 つのスレッドで構成され、マルチスレッドプロセスは複数のスレッドで構成されています。すべてのスレッドは、そのプログラムに割り当てられた共通アドレス空間を共有します。POSIX pthread の API を使用するプログラムは、 ユーザースレッド と呼ばれるものを作成し処理します。 カーネル スレッドは、カーネルがスケジューリングできるエンティティであり、1 つまたは複数のユーザースレッドをサポートすることができます。 HP-UX リリース 11i バージョン 1.6 以降では、HP-UX のスレッドの実装では、ユーザースレッドとカーネルスレッド間で、1 対 1 のマッピングだけでなく N 対 1 のマッピングもサポートしています。 各スレッドには、作成時に pthread_t 型の固有の識別子が割り当てられます。スレッド id は、プロセス専用の値であり、処理系に依存します。この値はスレッドにとって不明瞭なハンドルとみなされますのでアプリケーションでは使用しないでください。 インタフェースに関する注記HP-UX システムでは、pthread の API への標準的でない拡張をいくつか行っています。これらの拡張には、他と区別するために、常に _np または _NP (non-portable) という接尾辞が付いています。 プログラマは、使用する関数について必ずマンページを調べてください。標準的に指定される関数の中には、使用できないものや、一部の処理系では効果がないものがあります。 スレッドの作成/消去プログラムは、 pthread_create() 関数を使用してスレッドを作成します。スレッドは、その作業を終了したときに、 pthread_exit() 関数を呼び出してもかまいませんし、単にその最初の関数から戻ってもかまいません。 スレッドは、 pthread_join() 関数を使用することによって、他のスレッドの完了を検出することができます。
PTHREAD の属性スレッド属性の集合を pthread_create() に与えることができます。 デフォルト値の変更は、すべて pthread_create() の呼び出しを行う前に、属性集合に対して行わなければなりません。この呼び出しの後に属性集合を変更しても、作成されたスレッドには影響を与えません。ただし、属性集合は複数の pthread_create() の呼び出しで使用することができます。 スレッドの "detachstate"、"schedparam"、"schedpolicy"、および "processor" 属性だけは、スレッド作成の後に影響を受ける可能性があることに注意してください。ただしこれらの属性は、それぞれ、 pthread_detach()、 pthread_setschedparam() および pthread_processor_bind_np() 関数によって変更されます。
pthread_attr_getdetachstate(),
キャンセル一部のアプリケーションでは、プロセス全体を終了することなく、特定のスレッドを終了することを要求する場合があります。キャンセル対象スレッドがシステムコールまたは特定のライブラリルーチンを実行している間に、そのスレッドが同じプロセス内の別のスレッドによってキャンセルされる可能性があります。 あるスレッドが別のスレッドに対してキャンセル要求を発行する場合、キャンセル対象スレッドは、 pthread_testcancel() インタフェースによって、保留中のキャンセル要求があるかどうかをチェックすることができます。保留中のキャンセル要求によって呼び出された場合、キャンセル対象スレッドは、インストールされたすべてのクリーンアップハンドラーを実行した後に終了します。クリーンアップハンドラーは、このキャンセルされるスレッドによって割り当てられている動的記憶領域を削除したり、mutex ロックを解除したり、またはその他の処理のために使用されます。 一般に、スレッドのキャンセルタイプは、 deferred です。 つまりキャンセル要求は、そのスレッドがライブラリ関数またはシステムコールのリスト (下記のリストを参照) の 1 つである キャンセル ポイントに到達するまで、保留状態のままです。 スレッドは、そのキャンセルタイプを非同期 に設定することができます。この場合、キャンセル要求はその時点で処理されます。 これは、キャンセルポイントとなる関数を呼び出さないコンピュートバウンドのスレッド内で効果的に使用することができます。
pthread_setcancelstate(),
pthread_cleanup_pop(),
pthread ライブラリ、システム関数、libc でのキャンセルポイントのリストについては、 thread_safety(5) を参照してください。 libc 関数の場合、スレッドがキャンセルされるかどうかは、関数の実行中にどのような処理が行われたかによって決まります。 スレッドが関数内部でブロックした場合、キャンセルポイントが作成されます (つまり、そのスレッドはキャンセルされる可能性があります)。 その他のライブラリでも、キャンセルポイントがあることがあります。 詳細は、ライブラリに添付されているドキュメントを参照してください。 キャンセルポイントのリストは、リリースごとに異なります。 一般に、関数が EINTR エラーで戻る場合は、その関数がキャンセルポイントとなる可能性があります。 スケジューリングスレッドは個々にそれぞれのスケジューリング方針および優先順位を制御することができます。スレッドは、そのスレッドの実行、または他のスレッドの実行を一時停止することもできます。つまり、スレッドにはプロセッサの資源の割り当ての他にいくつかの制御が与えられています。
pthread_continue(),
pthread_num_processor_np(),
pthread_getconcurrency(),
pthread_getschedparam(),
sched_get_priority_max(),
通信および同期化マルチスレッドのアプリケーションは、並列に複数の命令を実行します。 プロセス全体にわたる (またはプロセス内の) 共有資源 (メモリー、ファイル記述子など) へのアクセスには、スレッド間の調整つまり同期のための制御が必要です。 libpthread ライブラリは、決定性アプリケーションを作成するために必要な同期的基本関数を提供します。マルチスレッドのアプリケーションは、強制的に非同期スレッドのコンテキストを同期させたり、順番に実行したり、実行中に管理および処理されるデータ構造および資源にアクセスしたりすることによって、決定性を保証します。これらは、相互排他 (mutex) ロック、条件変数、および読み込み/書き込みロックです。HP-UX オペレーティングシステムでも、POSIX セマフォを提供しています (次の項を参照してください)。 Mutexes は、並列して行われる変更からデータ構造を排他的に保護する手段を与えます。それらのプロトコルは、ロックを行っているスレッドが類似の mutex のロックを解除するまで、保護された構造内容が変更されるのを妨ぐことができます。mutex は、 pthread_mutex_init() の呼び出し、または PTHREAD_MUTEX_INITIALIZER の割り当てという 2 通りの方法で初期化することができます。 条件変数 は、スレッドによって使用され、特定のイベントの発生を待ちます。このようなイベントを検出したり引き起こしたりするスレッドには、 signal または broadcast があり、これらは待ち状態の 1 つまたは複数のスレッドを発生させます。 読み込み/書き込みロック では、読み込み/書き込みロックによって保護されている構造への複数のスレッドによる並列読み込みアクセスが許可されますが、書き込みアクセスを許可されるスレッドは 1 つだけです。 pthread_mutex_init(),
pthread_mutex_lock(),
pthread_mutex_getprioceiling(),
pthread_mutexattr_init(),
pthread_mutex_getyieldfreq_np(),
pthread_cond_init(),
pthread_cond_signal(),
pthread_condattr_init(),
pthread_rwlock_init(),
pthread_rwlock_rdlock(),
pthread_rwlockattr_init(),
POSIX 1.b のセマフォPOSIX 1.b 規格で指定されるセマフォ関数も、マルチスレッドのアプリケーションでの同期化のために使用することができます。 sem_init(),
sem_post(),
シグナルマルチスレッド処理では、すべてのスレッドは、シグナル動作を共有します。つまり、あるスレッドによって設定されたシグナルハンドラーがすべてのスレッドによって使用されます。 ただし、各スレッドに個別のシグナルマスクがあり、これによってスレッドは選択的にシグナルをブロックすることができます。 同じプロセス内の他のスレッドまたは他のプロセスにシグナルを送ることができます。シグナルがプロセスに送られると、そのシグナルをブロックしていないスレッドの 1 つが処理を行います。同じプロセス内のスレッドにシグナルが送られると、おそらく後でそのシグナルがブロックされる場合でも、そのスレッドがそのシグナルを処理します。終了、停止、または続行の動作を指すシグナルは、特定のスレッドで指示された場合でも、それぞれ、プロセス全体を終了、停止、または続行します。
sigwait(),
スレッド固有データスレッド固有データ (TSD) は、スレッドに専用の、つまり固有のグローバルデータです。各スレッドは、同じスレッド固有データ変数に対して異なる値を持ちます。グローバルな errno はスレッド固有のグルーバルデータの典型的な例です。 各スレッド固有のデータ項目は、キーに関連付けられています。このキーは、すべてのスレッドによって共有されます。ただし、スレッドがこのキーを参照する場合は、データの独自の専用コピーを参照します。 pthread_key_create(),
pthread_getspecific(),
HP-UX コンパイラは、 スレッドローカル記憶領域 (TLS) という記憶領域のクラスをサポートします。(これは、POSIX の標準的な機能ではありません。) TLS は、値の作成/設定/取得のために関数が必要でないこと以外は、TSD と同じです。TLS 変数は、通常のグローバル変数とまったく同様にアクセスされます。TLS 変数は、次の構文を使用して宣言することができます。 __thread int zyx; キーワード __thread は、 zyx が TLS 変数であることをコンパイラに指示します。現在、各スレッド次のような文によって TLS を設定または取得することができます。 zyx = 21; 各スレッドは、 zyx に異なる値を関連付けます。 TLS 変数は静的に初期化することができます。 初期化されていない TLS 変数には 0 が設定されます。 動的にロードされるライブラリ (shl_load() を使用) は、TLS 変数を宣言して使用することができます。 スレッドが TLS 変数を使用するかどうかにかかわらず、各スレッドのための TLS スペースを割り当てて初期化しなければならないので、TLS では、スレッド作成/終了処理に負担がかかります。 これは、起動時に静的にリンクされるモジールにあてはまります。 (sh_load() によって) 動的にロードされるライブラリの場合、スレッドの TLS スペースは、スレッドが TLS 変数にアクセスしたときに割り当てられます。 大きな TLS 領域を実際に使うスレッドがほとんどない場合は、代わりに POSIX TSD (上記) を使用することをお勧めします。 再入可能な LIBC および STDIOこれらは、ライブラリ内部の静的データを指すポンイタを返すので、マルチスレッドのプログラム内では多数の libc を使用することはできません。この理由は、スレッド内のこれらの関数の呼び出しによって他のスレッド内での以前の呼び出しの結果が上書きされるからです。 スレッドプログラムの作成のためには、 接尾辞 _r (再入可能を表す) が付いた代わりの関数が libc 内に用意されています。 さらに、標準的な I/O 動作の同期化のために、いくつかの基本関数が用意されています。 asctime_r(),
flockfile(),
その他の関数この項では、これまでに説明していないその他の pthread に関連する関数の概要を示します。
スレッドのデバッグマルチスレッドのプログラムのデバッグは、標準的な HP-UX デバッガ dde でサポートされています。 デバッガイベントによってあるスレッドが停止すると、デバッガはすべてのスレッドを停止します。任意のスレッドのレジスタの状態、スタック、およびデータを調べて操作することができます。 詳細については、 dde(1) マンページおよび組み込みのグラフィック ヘルプシステムを参照してください。 トレース機能HP-UX では、pthread の処理のためにトレース機能を用意しています。これを使用するためには、次のようにして、トレースバージョンのライブラリを使用してアプリケーションをリンクしなければなりません。 cc -D_POSIX_C_SOURCE=199506L -o myapp myapp.c -lpthread_tr -lcl アプリケーションは、実行されると、pthread イベントに関するスレッド単位のファイルを作成します。これは、 『HP/PAK パフォーマンス アプリケーションキット』 内で使用可能な ttv スレッドトレース表示機能への入力として使用されます。 トレースデータ ファイルを制御するために、下記の環境変数が定義されています。
トレースファイルのレコードフォーマットの詳細説明は、 /usr/include/sys/trace_thread.h にあります。 トレース情報の使用に関する詳細については、 ttv(1) マンページおよび組み込みのグラフィック ヘルプシステムを参照してください。 パフォーマンスに関する考察シングルスレッドよりもパフォーマンスを向上させるために、アプリケーションをマルチスレッドにするように設計する場合が多くあります。ただし、マルチスレットアプローチでは、シングルスレッドの場合にはほとんど関係のない問題に注意が必要です。これらは、従来からマルチプロセッサシステムのプログラミングに関連する問題です。 この設計には、データ構造およびアクセスパターンに適した大きさのデータ に分けてロックしなければなりません。 比較的大量の データに分けてロックし、保護する場合、不必要なロックの競合 を引き起こし、アプリケーションの並列処理能力を減少させることがあります。 他方、 非常に少量の データに分けてロックし、保護する場合、ロック動作が多きくなり、プロセッサが無駄な処理を行わなければならなくなる可能性があります。 スレッド固有データ (TSD) を使用すること、およびスレッドローカル 記憶領域 (TLS) を使用することは、上で説明したように (スレッド固有データ を参照)、トレードオフになります。 Mutex の spin および yield frequency 属性を使用すると、アプリケーションへの mutex の動作を調整することができます。 詳細については、 pthread_mutexattr_setspin_np(3T) および pthread_mutex_setyieldfreq_np(3T) を参照してください。 default stacksize 属性を設定すると、システムスレッドのキャッシュ動作を向上させることができます。 詳細については、 pthread_default_stacksize_np(3T) を参照してください。 複数のスレッドは、実際には同時に実行しているので、複数のプロセッサから同じデータをアクセスしている可能性があります。 ハードウェアプロセッサがそれぞれのデータのキャッシュを調整するので、プロセッサが古いデータ を使用することはありません。 あるプロセッサがデータをアクセス (特に書き込み処理のために) する場合、他のプロセッサはそれぞれのキャッシュから古いデータを初期化しなければなりません。 複数のプロセッサが同一のデータの読み込み/書き込みを繰り返す場合、命令ストリームの実行を低速にするキャッシュスラッシング を引き起こす可能性があります。これは、複数のスレッドが同じハードウェアのキャッシュ可能な単位 (キャッシュライン と呼ばれる) にある別々のデータ項目をアクセスする場合にも発生することがあります。 後者の状況をフォールスシェアリング と呼びますが、これは、データの間隔を開けてこのような一般的な項目を互いに近くに保存しないようにすることによって、避けることができます。 用語集以下の用語の定義は、Scott J. Norton、Mark D. DiPasquale 共著によるテキスト「ThreadTime\c 」(Prentice-Hall、ISBN 0-13-190067-6、1996 年発行) から抽出したものです。 アプリケーション プログラミング インタフェース (API)インタフェースは、エンティティへのアクセスまたはエンティティ間の通信を行なう伝達手段です。プログラミングの世界では、インタフェースは、関数とのアクセス (または通信) がどのように行なわれるかを記述します。特に、パラメータの数、名前、および目的は、関数へのアクセス方法を表します。API は、関数へのアクセスを行なう機能です。 非同期キャンセルセーフキャンセル状態が PTHREAD_CANCEL_ENABLE に設定され、キャンセルタイプが PTHREAD_CANCEL_ASYNCHRONOUS に設定されているスレッドから呼び出すことができる関数です。 このような関数の中の 1 つでスレッドがキャンセルされた場合、その関数内に状態は残りません。これらの関数は、通常、その関数のタスクを実行するために資源を獲得することはありません。 非同期シグナルセーフ非同期シグナルセーフの関数は、シグナルハンドラーによって呼び出すことができる関数です。シグナルハンドラーによって安全に呼び出すことができる関数は、一連の限定された関数だけです。これらの関数のリストは、POSIX.1c 規格の 3.3.1.3 項に記載されています。 非同期シグナル非同期シグナルは、外部イベントにより生成されるシグナルです。 kill() により送信されるシグナルおよびタイマーの満了または非同期 I/O の完了によって生成されるシグナルは、すべて非同期に生成されるシグナルの例です。非同期シグナルは、プロセスに配信されます。シグナルは、すべて非同期に生成される可能性があります。 fork 時ハンドラーアプリケーションにより提供および登録され、 fork() 処理の前後に呼び出される関数です。これらの関数は、通常の場合、fork() の前にすべての mutex ロックを獲得し、fork() の後に親プロセスおよび子プロセスの両方でそれらの mutex ロックを解除します。 バリヤ関数アプリケーション内の指定した点で一定の数のスレッドを待たせる、つまり集める同期的基本関数。バリヤ関数は、次の作業に進む前にすべてのスレッドがなんらかの操作を完了していることをアプリケーションが保証する必要のある場合に使用されます。 バインドされたスレッドカーネルでスケジューリングされるエンティティに直接バインドされているユーザースレッド。このようなスレッドは、システムのスケジューリング範囲を含んでいるので、直接カーネルによってスケジューリングされます。 キャッシュスラッシングキャッシュスラッシングは、1 つのスレッドが異なるプロセッサ上で実行している状況です。キャッシュされたデータを異なるプロセッサのキャッシュへ、またはキャッシュから移動させます。キャッシュスラッシングにより、重大なパフォーマンスの低下が引き起こされる可能性があります。 キャンセルクリーンアップ ハンドラーアプリケーションにより提供および登録され、スレッドがキャンセルされる際に呼び出される関数です。これらの関数は、通常の場合、スレッドのキャンセル中に、スレッドのクリーンアップ処理を実行します。これらのハンドラーは、シグナルハンドラーに似ています。 条件変数条件変数は、スレッドがイベントを待つことができるようにするために使用される同期的基本関数です。条件変数は、作成側のスレッドが 1 つまたは複数の消費側のスレッドに何かを提供しなければならない、作成側と消費側のスレッド間の問題の中で使用されることが多くあります。 コンテキストの切り替え現在実行中のスレッドをプロセッサから削除し別のスレッドを実行する処理。コンテキストの切り替えでは、現在実行中のスレッドのレジスタの状態を保存して、次の実行のために選択されたスレッドのレジスタの状態を復元します。 クリティカルセクション最小単位で割り込みなしに完了しなければならないコードのセクションです。コードのクリティカルセクションは、通常の場合、グローバルな資源 (変数、データ構造、リンクされたリストなど) が変更されるセクションです。実行中の操作は、他のスレッドが矛盾した状態でクリティカルセクションを参照しないように、最小単位で完了しなければなりません。 デッドロックデッドロックは、1 つまたは複数のスレッドが実行できなくなったときに発生します。たとえば、スレッド A がロック 1 を設定し、ロック 2 でブロックされているとします。一方、スレッド B がロック 2 を設定し、ロック 1 でブロックされているとします。すると、スレッド A および B は、永久にデッドロック状態になります。デッドロックは、スレッドを持つ任意の数の資源で発生する可能性があります。 相互デッドロック は、2 つ以上のスレッドが関係します。 再帰 (または 自己) デッドロック は 1 つのスレッドだけが関係します。 アタッチ解除されたスレッドスレッドの終了時にシステムにより自動的に解放される資源を持つスレッド。アタッチ解除されたスレッドは別のスレッドによって結合することはできません。つまり、アタッチ解除されたスレッドは、終了状態を返すことはできません。 結合可能なスレッド別のスレッドが終了を待つことができるスレッド。結合可能なスレッドは、結合を行なうスレッドに終了状態を返すことができます。結合可能なスレッドは、終了後に別のスレッドによって結合されるまで、その状態を保持します。 カーネル空間カーネルプログラムは、この空間に存在します。カーネルコードは、この空間の中で最高の権限レベルで実行されます。通常の場合、権限レベルには、ユーザーコード用のレベル (ユーザーモード) とカーネルコード用のレベル (カーネルモード) の 2 つがあります。 カーネルスタックスレッドは、システムコールを行なう場合は、カーネルモードで実行します。カーネルモードの間、スレッドは、アプリケーションによって割り当てられたスタックを使用しません。代わりに、システムコール中は、別のカーネルスタックが使用されます。カーネルがスケジューリングするそれぞれのエンティティには、それがプロセス、カーネルスレッド、または軽量プロセスのどれでも、カーネルスタックが含まれます。スタックの一般的な説明については、スタック を参照してください。 カーネルスレッドカーネルスレッドは、スレッドライブラリ内にあるスレッド関数によって作成されます。カーネルスレッドは、オペレーティングシステム カーネルから見ることができる カーネルがスケジューリングするエンティティ です。カーネルスレッドは、通常の場合、1 つまたは複数のユーザースレッドをサポートします。カーネルスレッドは、ユーザースレッドに代って、カーネルコードまたはシステムコールを実行します。一部のシステムでは、カーネルスレッドを 軽量プロセス と呼ぶ場合があります。 スレッドの一般的な説明については、 スレッド を参照してください。 軽量プロセスカーネルがスケジューリングするエンティティ。一部のシステムでは、軽量プロセスをカーネルスレッドと呼ぶ場合があります。それぞれのプロセスには、1 つまたは複数の軽量プロセスが含まれます。1 つのプロセスの中にいくつの軽量プロセスが含まれるかは、そのプロセスがマルチスレッドプロセスであるかどうかおよびその程度によって決まります。スレッドの一般的な説明については、 スレッド を参照してください。 マルチスレッドアプリケーションに複数の実行スレッドを持つことを可能にするプログラミングモード。マルチスレッドにより、アプリケーションは (マルチプロセッサシステム上で) 同時並列処理を行なうことができます。 Mutexmutex は、相互排他同期的基本関数です。Mutex は、共有されるデータおよび資源へのアクセスを管理、または順番に実行する機能をスレッドに与えます。あるスレッドが mutex ロックを行なっている場合、このスレッドが mutex をロック解除するまで、mutex ロックを行なおうとしている他のスレッドはブロックされます。 POSIX移植可能なオペレーティングシステム インタフェース。POSIX は、アプリケーションを移植できるようにするために複数のベンダーが従う一連の規格を定義します。Pthreads の規格 (POSIX 1003.1c) は、アプリケーション開発担当者に一連の移植可能なマルチスレッド用 API を提供します。 優先順位の逆転優先順位の低いスレッドが優先順位の高いスレッドにより要求される資源を獲得している状況。この資源を獲得することができない場合、優先順位の高いスレッドはこの資源を待たなければなりません。最終的な結果として、優先順位の低いスレッドが優先順位の高いスレッドをブロックします。 プロセスプロセスは、1 つまたは複数のスレッドのための、実行、アドレス空間、および共有プロセスの資源の入れ物と考えることができます。すべてのプロセスは最低でも 1 つのスレッドを持ちます。プロセス内の各スレッドはそのプロセスのアドレス空間内で実行します。プロセスが共有する資源の例としては、オープンファイル記述子、メッセージ待ち行列記述子、mutex、およびセマフォがあります。 プロセス構造体オペレーティングシステムは、システム内のそれぞれのプロセスごとにプロセス構造体を持っています。この構造体は、システム内で内部的に実在するプロセスを表します。プロセス構造体情報のサンプルとしては、プロセス ID、プロセスのオープンファイルの集合、シグナルベクトルがあります。プロセス構造体およびその中に含まれる値は、プロセスのコンテキストの一部です。 読み込み/書き込みロック読み込み/書き込みロックは、同期的基本関数です。読み込み/書き込みロックは、プロセスが共有するデータおよび資源へのアクセスを管理、または順番に実行する機能をスレッドに与えます。読み込み/書き込みロックでは、複数の読み込みスレッドが同時に読み込みロックを獲得できるのに対して、同時に書き込みロックを獲得できる書き込みスレッドは 1 つだけです。これらのロックは、書き込みがまれにしか行われす、たいていは読み込みが行われる共有データに有効です。 スケジューリングの割り当てドメイン1 つのスレッドがスケジューリングされているプロセッサの集合。このドメインのサイズは、いつでも動的に変更することができます。スレッドをあるドメインから別のドメインに移動することもできます。 スケジューリングの競合範囲スケジューリングの競合範囲は、あるスレッドが資源のアクセスを競合するスレッドのグループを定義します。非常に多くの場合、競合範囲はプロセッサへのアクセスに該当します。ただし、この範囲は、複数のスレッドが他の資源を競合する場合にも使用することができます。システム範囲のスレッドは、そのシステム内の他のすべてのスレッドと資源へのアクセスを競合します。プロセス範囲のスレッドは、そのプロセス内の他のプロセス範囲のスレッドと資源へのアクセスを競合します。 スケジューリング方針スケジューリング方針は、複数のスレッドを実行するために、いつ、どのようにスケジューリングするかを決定するために使用される一連の規則です。スケジューリング方針は、どれだけ長くスレッドに実行を許可するかについても決定します。 スケジューリングの優先順位スケジューリングの優先順位は、一部のスケジューリング方針でスレッドに割り当てられる数値による優先順位の値です。優先順位の高いスレッドには、スケジューリングの決定を行う際に優先権が与えられます。 セマフォセマフォは mutex に似ています。セマフォは、1 つまたは複数の共有オブジェクトへのアクセスを管理します。セマフォには値が割り当てられます。この値は、通常の場合、そのセマフォによって管理される共有資源の数に設定されます。セマフォの値が 1 の場合には、バイナリセマフォです。基本的に、mutex はバイナリセマフォです。セマフォの値が 1 よりも大きい場合、 カウンティングセマフォ と呼ばれます。 カウンティングセマフォは、複数のスレッドによって同時にロックされる可能性があります。セマフォがロックされるたびに、この値は 1 つずつ減少していきます。この値がゼロになった後、そのセマフォを新たにロックしようとすると、そのセマフォが別のスレッドによってロック解除されるまで、ロックを行なおうとしているスレッドはブロックされます。 共有オブジェクト共有オブジェクトは、プロセスのアドレス空間に存在し、そのプロセス内のすべてのスレッドによってアクセス可能な実体のあるエンティティです。マルチスレッドプログラミングの場合、「共有オブジェクト」はグローバル変数、ファイル記述子、および、スレッドによるアクセスを同期させることを要求する他のオブジェクトです。 シグナルマスクシグナルマスクは、スレッドがどのシグナルを受け入れ、どのシグナルが配信からブロックされるかを決定します。同期シグナルは、配信からブロックされた場合、そのスレッドがそのシグナルのブロックを解除するかまたはそのスレッドが終了するまで、保留されたままです。プロセスに配信される非同期シグナルがあるスレッドによって配信からブロックされている場合、プロセス内でこのシグナルをブロックしていない別のスレッドがこのシグナルを処理することができます。 シグナルベクトルシグナルベクトルは、各プロセス内に含まれるテーブルで、それぞれのプロセス内のスレッドにシグナルが配信されたときに実行する動作を表します。それぞれのシグナルは、そのシグナルを無視する、シグナル処理関数を実行する、そのシグナルのデフォルトの動作 (通常は、プロセスの終了) を実行する、という 3 つの可能性のある動作の中の 1 つの動作を行ないます。 Spinlockmutex に似た同期的基本関数。mutex ロックを獲得できない場合、そのロックを獲得したいスレッドは、ブロックされる代わりに、そのロックを獲得できるまでループ内を回ります。Spinlock は不適切に使用されやすく、これをシングルプロセッサシステムで使用すると、パフォーマンスが著しく低下する可能性があります。 疑似起動スレッドを間違ってブロック解除すると、そのスレッドが待っていたイベントが発生しない場合でも、疑似起動が発生します。ブロックされているスレッドが通常のシグナルを受け取ったために、条件待ちが割り込みされて戻るのは、疑似起動の例です。 スタックスタックは、スレッドによって、関数呼び出しの実行 (およびこれらの呼び出しからの復帰)、関数呼び出しへの引き数の引き渡し、および、関数呼び出し時に呼び出された関数内でのローカル変数への空間の割り当てを行なうために使用されます。バインドされたスレッドには、ユーザースタックとカーネルスタックがあります。バインドされていないスレッドにはユーザースタックだけがあります。 同期シグナル同期シグナルは、特定のスレッドのある動作によって生成されるシグナルです。 たとえば、あるスレッドがゼロによる除算を行なったり、浮動小数点例外を引き起こしたり、不当な命令を実行したりすると、シグナルが同期的に生成されます。同期シグナルは、そのシグナルを送信させたスレッドに配信されます。 スレッドローカル記憶領域 (TLS)スレッドローカル記憶領域は、基本的には、コンパイラからのサポートを要求するスレッド固有データです。TLS によって、アプリケーションは、スレッド固有のデータキーを使用するのではなく、実際のデータをスレッド固有のデータとして割り当てることができます。さらに、TLS では、スレッド固有データを取得するためにスレッドが関数呼び出しを行う必要はありません。スレッドは、このデータを直接アクセスすることができます。 スレッドセーフの関数スレッドセーフの関数は、複数のスレッドによって同時に安全に呼び出すことができる関数です。この関数が共有データまたは資源をアクセスする場合、そのアクセスは mutex または何か別の形式の同期制御によって管理されます。 スレッド固有データ (TSD)スレッド固有データは、スレッドに固有のグローバルデータです。すべてのスレッドは、同じデータ変数をアクセスします。ただし、各スレッドは、この変数に対してスレッド独自の値を持ちます。errno は、スレッド固有データの例です。 スレッド構造体オペレーティングシステムは、システム内のそれぞれのスレッドごとにスレッド構造体を持っています。この構造体は、システム内で内部的に実在するスレッドを表します。スレッド構造体情報のサンプルとして、スレッド ID、スケジューリング方針および優先順位、シグナルマスクがあります。スレッド構造体およびその中に含まれる値は、スレッドのコンテキストの一部です。 ユーザーモード操作のサブセットが許可される操作モード。スレッドは、アプリケーションコードの実行中は、ユーザーモードで実行しています。スレッドは、システムコールを行なう場合には、モードを変更して、そのシステムコールが完了するまでカーネルモードで実行します。 ユーザー空間ユーザーコードは、この空間に存在します。ユーザーコードは、この空間の中で通常の権限レベルで実行されます。通常の場合、権限レベルには、ユーザーコード用のレベル (ユーザーモード) とカーネルコード用のレベル (カーネルモード) の 2 つがあります。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||