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

新しい sigwait の実装

Solaris オペレーティング環境 2.5 以降のリリースでは、Solaris オペレーティング環境 2.5 バージョンの新しい sigwait() と POSIX.1c バージョンの sigwait() の 2 種類を使用できます。新しいアプリケーションとライブラリでは、できるだけ POSIX 規格インタフェースを使用してください。Solaris オペレーティング環境バージョンは、将来のリリースではサポートされない可能性があるからです。


注 -

Solaris オペレーティング環境 2.5 バージョンの新しい sigwait() は、シグナルの無視という処置を無効にしません。以前の sigwait(2) の動作に依存しているアプリケーションは、ダミーのシグナルハンドラをインストールして、その処置を SIG_IGN からハンドラをもつように変更しない限りブレークする可能性があるため、このシグナルに対する sigwait() 呼び出しでこのシグナルは捕捉されます。


これら 2 つのバージョンの sigwait() の構文は下記のとおりです。


#include <signal.h>

/* Solaris 2.5 バージョン */
int sigwait(sigset_t *set);

/* POSIX.1c バージョン */
int sigwait(const sigset_t *set, int *sig);

指定のシグナルが送られてくると、POSIX.1c sigwait() は保留されているそのシグナルを削除し、sig にそのシグナルの番号を入れます。同時に複数のスレッドから sigwait() を呼び出すこともできますが、受け取るシグナルごとに 1 つのスレッドだけの sigwait() だけが返ってきます。

sigwait() を使うと、非同期シグナルを同期的に扱うことができます。つまり、非同期シグナルを扱うスレッドから sigwait() だけを呼び出すと、シグナルが到着しだい戻ります。sigwait() の呼び出し側も含むすべてのスレッドで非同期シグナルをマスクすることによって、非同期シグナルを特定のシグナルハンドラだけに処理させることができます。非同期シグナルを安全に処理することが可能です。

すべてのスレッドですべてのシグナルを常にマスクし、必要なときだけ sigwait() を呼び出すようにすれば、アプリケーションはシグナルに依存するスレッドに対してはるかに安全になります。

通常、sigwait() を使うときは、シグナルを待つスレッドを 1 つまたは複数生成します。sigwait() はマスクされているシグナルであっても受け取るため、それ以外のスレッドでは誤ってシグナルを受け取ることがないように、対象となるシグナルをすべてブロックしてください。

シグナルが送られてくると、スレッドは sigwait() から復帰し、シグナルを処理し、さらに次のシグナルを待ちます。このシグナル処理スレッドでは、非同期保護関数以外の関数も使用でき、他のスレッドとも通常の方法で同期をとることができます (非同期保護カテゴリについては、「マルチスレッドインタフェースの安全レベル」を参照してください)。


注 -

同期シグナルに対しては、sigwait() を決して使わないでください。