マルチスレッドのプログラミング

タイマ、アラーム、およびプロファイル

LWP ごとのタイマ (timer_create(3R) を参照) とスレッドごとのアラーム (alarm(2) または setitimer(2) を参照) についての「サポート中止」のご案内が Solaris 2.5 リリースでされています。どちらの機能も、この節で説明するプロセスごとの代替物によって補足されています。

各 LWP は、その LWP に結合されているスレッドが使用できるリアルタイムインタバルタイマとアラームを持っています。このタイマとアラームは、一定時間が経過すると 1 つのシグナルをスレッドに送ります。

各 LWP は、その LWP に結合されているスレッドが使用できる仮想時間インタバルタイマ、またはプロファイル用のインタバルタイマも持っています。このインタバルタイマは一定時間が経過すると、それを所有している LWP に SIGVTALRM シグナルまたは SIGPROF シグナルを送ります。

LWP ごとの POSIX タイマ

Solaris 2.3 と 2.4 リリースでは、timer_create(3R) 関数が戻すタイマオブジェクトは、そのタイマ ID が呼び出し LWP の中だけで意味をもち、その期限切れシグナルが呼び出し LWP に送られるというものでした。このため、POSIX タイマ機能を使用できるスレッドは、結合スレッドに限られていました。

さらに、この制限された使用方法でも、Solaris 2.3 と 2.4 リリースのマルチスレッドアプリケーションでの POSIX タイマは、生成されるシグナルのマスキングおよび sigvent 構造体からの関連値の送信について信頼性に欠けるところがありました。

Solaris 2.5 以降のリリースでは、マクロ _POSIX_PER_PROCESS_TIMERS を定義してコンパイルされたアプリケーション、あるいはシンボル _POSIX_C_SOURCE に対して 199506L より大きな値を指定してコンパイルされたアプリケーションは、プロセスごとのタイマを作成できます。

Solaris 2.5 リリースより前のリリースでコンパイルされたアプリケーション、あるいは機能評価マクロを使わずにコンパイルされたアプリケーションは、引き続き LWP ごとの POSIX タイマを作成します。将来のリリースでは、LWP ごとのタイマを作成するための呼び出しが、プロセスごとのタイマを戻すようになる予定です。

プロセスごとのタイマのタイマ ID は、どの LWP からでも使用できます。期限切れシグナルは、特定の LWP に向けられるのではなく、そのプロセスに対して生成されます。

プロセスごとのタイマは、timer_delete(3R) の呼び出し時またはそのプロセスの終了時にのみ削除されます。

スレッドごとのアラーム

Solaris オペレーティング環境 2.3 と 2.4 リリースでは、alarm(2) または setitimer(2) の呼び出しは、呼び出し LWP の中だけで意味をもっていました。生成した LWP が終了すると、こうしたタイマは自動的に削除されました。このため、alarm()setitimer() を使用できるスレッドは、結合スレッドに限られていました。

さらに制限された使用方法でも、Solaris オペレーティング環境 2.3 と 2.4 のマルチスレッドアプリケーションでの alarm() タイマと setitimer() タイマは、これらの呼び出しを行なった結合スレッドからのシグナルのマスキングについて信頼性に欠けるところがありました。このようなマスキングが必要とされなければ、結合スレッドから出された、これら 2 つのシステムコールの動作は信頼できるものでした。

Solaris オペレーティング環境 2.5 以降のリリースでは、-lpthread (POSIX) スレッドとリンクしたアプリケーションは、alarm() を呼び出したときにプロセスごとの SIGALRM 通知を受けるようになります。alarm() で生成される SIGALRM は、特定の LWP に向けられるのではなく、そのプロセスに対して生成されます。このアラームは、そのプロセスの終了時にリセットされます。

Solaris オペレーティング環境 2.5 リリースより前のリリースでコンパイルされたアプリケーション、あるいは -lpthread とリンクされていないアプリケーションは、alarm() または setitimer() で生成されるシグナルの、LWP ごとの送信を引き続き行います。

将来のリリースでは、ITIMER_REAL フラグを指定した alarm() または setitimer() の呼び出しによって、SIGALRM がそのプロセスに送られる予定です。他のフラグについては、setitimer() で引き続き LWP ごとの送信が行われる予定です。setitimer() のフラグで ITIMER_REAL フラグ以外のものについては、生成されるシグナルが、その呼び出しを行なった LWP に送信されることに変わりはなく、したがって結合スレッドからしか使用できません。

プロファイル

profil(2) で、各 LWP に専用のバッファ、または複数の LWP で共有のバッファを用意することにより、LWP ごとにプロファイルを有効にすることが可能です。プロファイルデータの更新は、LWP ユーザ時間のクロック更新単位ごとに行われます。プロファイルの状態は、生成元の LWP から継承されます。