【作業記録】シグナル

  • シグナルについて調査してみた件
  • プロセスをシェルから起動し、端末から Ctrl - c でSIGINTを送る
  • プロセスは2つにforkする
  • プロセスは親子関係を持つが、シグナルはどうなるのか?

  • 書いてみたプログラム

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

typedef void (*sighandler_t)(int);

sighandler_t trap_signal(int sig, sighandler_t handler);
void sighandler(int sig);

int main(void)
{
    pid_t pid;
    pid = fork();

    if (pid != 0)
    {
        // 親プロセス
        fprintf(stderr, "(parent:%d) waiting for signal ...\n", getpid());
        trap_signal(SIGINT, sighandler);

        pause();

        fprintf(stderr, "(parent:%d) waiting for exit chiled ...\n", getpid());
        wait(NULL);

        fprintf(stderr, "(parent:%d) exit process\n", getpid());
        exit(EXIT_SUCCESS);
    }
    else
    {
        // 子プロセス
        fprintf(stderr, "(chiled:%d) waiting for signal ...\n", getpid());
        trap_signal(SIGINT, sighandler);

        pause();

        fprintf(stderr, "(chiled:%d) exit process\n", getpid());
        exit(EXIT_SUCCESS);
    }
}

sighandler_t
trap_signal(int sig, sighandler_t handler)
{
    struct sigaction act, old;

    act.sa_handler = handler;
    sigemptyset(&act.sa_mask);
    act.sa_flags = SA_RESTART;
    if (sigaction(sig, &act, &old) < 0)
        return NULL;

    return old.sa_handler;
}

void sighandler(int sig)
{
    fprintf(stderr, "(%d) handle signal : %d\n", getpid(), sig);
}
  • 2回動かしてみた結果
$ ./sigaction_propa 
(parent:5503) waiting for signal ...
(chiled:5504) waiting for signal ...
^C(5504) handle signal : 2
(chiled:5504) exit process
(5503) handle signal : 2
(parent:5503) waiting for exit chiled ...
(parent:5503) exit process
$ ./sigaction_propa 
(parent:5621) waiting for signal ...
(chiled:5622) waiting for signal ...
^C(5621) handle signal : 2
(parent:5621) waiting for exit chiled ...
(5622) handle signal : 2
(chiled:5622) exit process
(parent:5621) exit process
  • 伝搬というか、どちらにもシグナルが送られている感じ
  • 送られる順番は決まっていない
  • そもそもシグナルが非同期処理なので、順不同なのは当たり前かも?