SIGNAL を受信する
試しに実装してみた
大概の SIGNAL のサンプルソースだと、シグナル受けたよーで終わるのが多いけど、実際のプログラムの時はシグナルを受けたタイミングとプログラムの終了タイミングが異なるケースが多いので*1、後者の仕様で作成してみた。
受けるとる SIGNAL は SIGINT と SIGTERM にした。特に意味はない。
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <signal.h> #define SIGNAL_ON 0 #define SIGNAL_OFF 1 int is_signal_int = SIGNAL_OFF; int is_signal_term = SIGNAL_OFF; void signal_int(int signum, siginfo_t *info, void *ctx){ printf("signal[%d] signo(%d) code(0x%x)", signum, info->si_signo, info->si_code); is_signal_int = SIGNAL_ON; } void signal_term(int signum, siginfo_t *info, void *ctx){ printf("signal[%d] signo(%d) code(0x%x)", signum, info->si_signo, info->si_code); is_signal_term = SIGNAL_ON; } int main(void) { struct sigaction signal[2]; memset(&signal, 0, sizeof(signal)); // シグナルハンドラ設定: SIGINT signal[0].sa_sigaction = signal_int; signal[0].sa_flags = SA_RESTART | SA_SIGINFO; if (sigaction(SIGINT, &signal[0], NULL) < 0) { exit(2); } // シグナルハンドラ設定: SIGTERM signal[1].sa_sigaction = signal_term; signal[1].sa_flags = SA_RESTART | SA_SIGINFO; if (sigaction(SIGTERM, &signal[1], NULL) < 0) { exit(2); } // シグナルで停止するまで無限ループ while(1) { puts("while[start]..."); puts("ココの処理はかならずやり遂げるのだ!"); // SIGNAL を受けたかチェック if(is_signal_term == SIGNAL_ON || is_signal_int == SIGNAL_ON) { puts("終了しまーす"); exit(1); } puts("while[end]..."); sleep(3); } return 0; }
SIGNAL 送信と終了のタイミングを非同期にする為、 SIGNAL を受信したタイミングでグローバル変数に受信したよフラグを保存して、プログラム中の任意の場所でグローバル変数の状態を見て終了する。
補足のエントリを書きました
別に大した内容ではないけれど、ちょっと解説的なものを。
SIGNAL を受信する(2) - @sugamasao.blog.title # => ”コードで世界を変えたい”
*1:例えば、終了シグナルを受けたら処理中のファイルは保存しておく、等