○シグナル(割り込み)

signal(シグナル番号,アクション);

アクションは割り込む関数アドレスまたは、
    SIG_DFL	デフォルト動作
    SIG_IGN	シグナルを無視 (ただしSIGKILLは無視できない)

(SIGKILLの場合は関数アドレスの指定も不可)

■シグナル番号一覧

SIGHUP		グループリーダープロセスの終了
SIGINT		インタラプト文字の入力
SIGQUIT		クイット文字の入力
SIGILL		未定義命令の実行 
SIGTRAP		トレーストラップ 
SIGABRT		abort()を実行 
SIGEMT		out-of-memory (強制的に終了 捕まえることはできない)
SIGFPE		浮動小数点例外 
SIGKILL		kill,killallコマンド (強制的に終了 捕まえることはできない)
SIGBUS		CPU バスエラー 
SIGSEGV		セグメント違反 (割り込み動作はするが無効にできない(割り込み後、プログラム終了))
SIGHSYS		システムコールの引数の不当 
SIGPIPE		パイプの切断通知
SIGALRM		alarm()コールの結果
SIGTERM		killコマンド
SIGUSR1		ユーザ定義のシグナル1 
SIGUSR2		ユーザ定義のシグナル2 
SIGCHLD		子プロセス終了 
SIGPWR		電源障害の再起動 
SIGSTOP		一時停止 
SIGCONT		電源異常復旧

■実行中にCTRL+Cが押されるとシグナルにより終了します(デフォルト処理)

#include <stdio.h>
#include <signal.h>

main(){
	signal(SIGINT,SIG_DFL);
	while(1){
		printf("%s\n","無限ループ");
	}
}

■実行中にCTRL+Cが押されるとシグナルにより割り込みが発生します

#include <stdio.h>
#include <signal.h>

void fanc(){
	printf("%s\n","インタラプト文字の入力");
	getchar();
}

main(){
	signal(SIGINT,fanc);
	while(1){
		printf("%s\n","無限ループ");
	}
}

■実行中にCTRL+Cが押されても無視します

#include <stdio.h>
#include <signal.h>

main(){
	signal(SIGINT,SIG_IGN);
	while(1){
		printf("%s\n","無限ループ");
	}
}

▼sleepの戻り値に残りの時間が戻ってきます

#include <stdio.h>
#include <signal.h>

void fanc(){
	printf("%s\n","インタラプト文字の入力");
}

main(){
	signal(SIGINT,fanc);
	int i=sleep(10);
	printf("スリープはあと%d秒ありました\n",i);
}

■自分の強制終了

自分のプロセスにSIGABRTを送ります
プロセスが終了しコアイメージがダンプされます

#include <stdio.h>
#include <signal.h>

main(){
	abort();
}

■不正なメモリアクセスを検出

#include <stdio.h>
#include <signal.h>

int i,j;
	
void func(){
	printf("%s %d\n","不正なメモリをアクセス",i);
	exit(0);
}

main(){
	char a[10];
	signal(SIGSEGV,func);

	while(1){
		//不正なメモリアクセスを行う
		j=a[i++];
		printf("%d\n",i);
	}
}


■アラーム
alarm(秒)

指定した秒の経過後にSIGALRMを発生します。

#include <stdio.h>
#include <signal.h>

void func(){
	printf("%s\n","アラーム");
	alarm(1);
}

main(){
	signal(SIGALRM,func);
	alarm(1);
	while(1){}
}

■アラームシグナルを受けるまで停止
pause()

シグナルを受けるまでその場でプログラムが停止します

#include <stdio.h>
#include <signal.h>

void func(){
	printf("%s\n","アラーム");
	alarm(1);
}

main(){
	signal(SIGALRM,func);
	alarm(1);
	pause();//シグナルを受けるまで停止
	alarm(1);
	pause();
	printf("%s\n","終了");
}

■プロセスの強制終了
kill

▼同じグループIDを持つプロセス全てにシグナルを送信
シグナル番号に 0 を入れる

#include <stdio.h>
#include <signal.h>

main(){
	if(fork()){
		while(1){
				printf("%s\n","私は子供");
		}
	}
	sleep(4);
	kill(0,1);//自分と同じグループIDを持つプロセス全てにシグナルを送信
	printf("%s\n","終了");
}

▼PIDに対してシグナルを送信
kill(PID,1)

#include <stdio.h>
#include <signal.h>

main(){
	int PID=fork();
	if(PID==0){
		while(1){
				printf("%s\n","私は子供");
		}
	}
	sleep(2);
	kill(PID,1);//PIDに対してシグナルを送信
	sleep(2);
	printf("%s\n","終了");
}

▼PIDのプロセスが存在するか確認
if(kill(プロセスID,0)!=EOF) プロセスは存在する

#include <stdio.h>
#include <signal.h>

main(){
	int PID;
	for(PID=1;PID<=32768;PID++){
		if(kill(PID,0)!=EOF) printf("%d\n",PID);
	}
	printf("%s\n","終了");
}




▲トップページ > Linux と C