[C/C++] シグナルを受け取る、シグナルハンドルをする



C言語を利用してシグナルをハンドルしてみましょう。ターミナルなどからシグナルを発行することで制御を変えることが可能です。

スポンサードリンク

ソースコード

#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

static int g_hoge = 0;

/* シグナルハンドラ */
void sig_handler(int signo)
{
    if (signo == SIGUSR1) {
        printf("received SIGUSR1\n");
    } else if (signo == SIGKILL) {
        printf("received SIGKILL\n");
    } else if (signo == SIGSTOP) {
        printf("received SIGSTOP\n");
    } else if (signo == SIGTERM) {
        printf("received SIGTERM\n");
    }
    g_hoge = 1;
}

int main(void)
{
    /* シグナルハンドラの設定 */
    if (signal(SIGUSR1, sig_handler) == SIG_ERR) {
        printf("\ncan't catch SIGUSR1\n");
    }

    /* シグナルハンドラの設定 */
    if (signal(SIGTERM, sig_handler) == SIG_ERR) {
        printf("\ncan't catch SIGUSR1\n");
    }

    /* シグナルハンドラの設定 */
    if (signal(SIGKILL, sig_handler) == SIG_ERR) {
        printf("\ncan't catch SIGKILL\n");
    }

    /* シグナルハンドラの設定 */
    if (signal(SIGSTOP, sig_handler) == SIG_ERR) {
        printf("\ncan't catch SIGSTOP\n");
    }

    /* シグナルを受け取るまで無限ループ */
    while(1) {
        if (g_hoge == 1) break;
        sleep(1);
    }

    printf("the end\n");
    return 0;
}

「SIGKILL」と「SIGSTOP」は、シグナルを受け取る事はできません。

代表的なシグナル

シグナル番号 シグナル名 説明
1 SIGHUP デーモンプロセスに設定の再読み込みをさせるのに利用される
2 SIGINT キーボードからの割り込み(Ctrl-C)
3 SIGQUIT キーボードからのプロセスの中止(Quit)
4 SIGILL 不正な命令(Illegal instruction)によるプロセスの中止
9 SIGKILL Kill シグナル。kill -kill [PID]
14 SIGALRM アラーム。一定時間後にSIGALRMを飛ばせる
15 SIGTERM 終了シグナル。kill -term [PID]

スポンサードリンク

ビルド方法

g++ signal.cpp

結果

$ ./a.out &
can't catch SIGKILL

can't catch SIGSTOP

$ ps u
USER    PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
hoge   7024  0.0  0.0  22168  3664 pts/0    Ss   May07   0:00 -bash
hoge  16351  0.0  0.0  11732   868 pts/0    S    13:03   0:00 ./a.out
hoge  16352  0.0  0.0  15520  1208 pts/0    R+   13:03   0:00 ps u

$ kill -USR1 16351 ← ./a.out の PID
received SIGUSR1
the end

スポンサードリンク