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

スレッド指定シグナル

UNIX のシグナル機構が、スレッド指定シグナルの概念で拡張されています。スレッド指定シグナルは、プロセスではなく特定のスレッドに送られるという点を除いて、通常の非同期シグナルと似ています。

独立したスレッドで非同期シグナルを待つほうが、シグナルハンドラを実装して、そこでシグナルを処理するよりも安全で簡単です。

非同期シグナルを処理するよりよい方法は、非同期シグナルを同期的に処理することです。sigwait(2) を呼び出すことにより、スレッドはシグナルの発生まで待機できます。「特定のシグナルの待機」を参照してください。


例 5–2 非同期シグナルと sigwait(2)

main() {
    sigset_t set;
    void runA(void);
    int sig;

    sigemptyset(&set);
    sigaddset(&set, SIGINT);
    pthread_sigmask(SIG_BLOCK, &set, NULL);
    pthread_create(NULL, 0, runA, NULL, PTHREAD_DETACHED, NULL);

    while (1) {
        sigwait(&set, &sig);
        printf("nestcount = %d\n", nestcount);
        printf("received signal %d\n", sig);
    }
}

void runA() {
    A(4,4);
    exit(0);
}

この例は、例 5–1 のコードを修正したものです。メインルーチンは SIGINT シグナルをマスクし、関数 A を呼び出す子スレッドを生成し、最後に sigwait() を呼び出して SIGINT シグナルを待ちます。

対象となるシグナルが、計算を行うためのスレッドでマスクされていることに注目してください。計算を行うためのスレッドは、メインスレッドのシグナルマスクを継承するからです。メインスレッドは SIGINT から保護されており、sigwait() の内部でだけ SIGINT に対するマスクが解除されます。

また、sigwait() を使用しているとき、システムコールの割り込みの危険がない点にも注目してください。