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

特定のシグナルの待機

マルチスレッドプログラムでは、sigwait(2) が優先インタフェースです。これは、非同期シグナルを正しく処理できるからです。()

sigwait() は、sigwait() 関数の set 引数に指定したシグナルが呼び出しスレッドに送られてくるまで、そのスレッドを待ち状態にします。スレッドが待っている間は、set 引数で指定したシグナルのマスクが解除され、復帰時に元のシグナルマスクが設定し直されます。

set 引数で識別されるすべてのシグナルは、呼び出しスレッドを含むすべてのスレッドでブロックする必要があります。そうしないと、sigwait() は正確に動作しません。

非同期シグナルからプロセス内のスレッドを隔離したい場合は、sigwait() を使用します。非同期シグナルを待つスレッドを 1 つ生成しておき、ほかのスレッドは、現在のプロセスに送られてくる可能性のある非同期シグナルをすべてブロックするようにすることができます。

次の例は、sigwait() の構文を示しています。

#include <signal.h>
int sigwait(const sigset_t *set, int *sig
);

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

sigwait() では、非同期シグナルを同期的に扱うことができます。こうしたシグナルを扱うスレッドは、sigwait() を呼び出したあと、シグナルが到着するとすぐ終了します。sigwait() の呼び出し側を含むすべてのスレッドで非同期シグナルをマスクすることによって、非同期シグナルを特定のシグナルハンドラだけに安全に処理させることができます。

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

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

シグナルを受け取ったシグナル処理スレッドは、sigwait() から復帰してそのシグナルを処理したあと、sigwait() を再度呼び出して次のシグナルを待機します。このシグナル処理スレッドは、非同期シグナル安全関数以外にも使用できます。このシグナル処理スレッドは、ほかのスレッドとも通常の方法で同期をとることができます。非同期シグナル安全カテゴリについては、「マルチスレッドインタフェースの安全レベル」を参照してください。


注 –

sigwait() は、非同期シグナルを受け取れません。