UNIX のシグナル機構が、スレッド指定という考え方で拡張されています。これは、シグナルがプロセスではなく特定のスレッドに送られるという点を除いて、通常の非同期シグナルと似ています。
独立したスレッドで非同期シグナルを待つ方が、シグナルハンドラを実装して、そこでシグナルを処理するよりも安全で簡単です。
非同期シグナルを処理するよりよい方法は、非同期シグナルを同期的に処理することです。具体的には、「sigwait(2)」で説明した sigwait(2) を呼び出すことにより、スレッドはシグナルの発生を待つことができます。
main() { sigset_t set; void runA(void); int sig; sigemptyset(&set); sigaddset(&set, SIGINT); pthread_sigsetmask(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() を使用しているとき、システムコールから割り込まれる危険性がないことも注目してください。