개발자/Raspberry Pi

sudo kill -9 pid 로 발생하는 메세지 처리, kill 메세지 처리

지구빵집 2016. 12. 8. 16:00
반응형





결론적부터 말하자면 리눅스에서 시스템 메세지 발생하는 것 중에 SIGKILL과 SIGSTOP 메세지는 사용자가 처리할 수 없다.


아래 설명을 참고 하고, 해결방법은 SIGTERM 메세지를 사용한다. 비정상적으로 동작하는 프로세스는 당연히 

$sudo kill -9 PID 로 죽이는게 맞으니, 굳이 정상 종료되로록 SIGTERM 을 사용 할 필요가 없으니, 어쩌면 백그라운드로 돌아가는 프로그램을 죽이는 명령은 SIGTERM(15번 메세지)을 사용해서 죽인는게 맞다고 생가된다.


$sudo  kill -15 PID 하면 이때 SIGTERM 메세지가 발생하고 이걸로 뒷처리를 한다.


참고로 ctrl-c 로 종료할때 SIGINT 메세지 사용방법과 예제코드는 이곳에서 참고한다.


http://fishpoint.tistory.com/1519  -- 

ctrl-c 프로세스 종료시 주의할 점과 SIGINT 시그널 사용법


kill은 유닉스 계열 운영 체제에서 시스템상에서 동작하고 있는 프로세스에 간단한 메시지(시그널)를 보내는 명령어이다. 기본적으로 보내는 메시지는 종료 메시지이고 프로세스에 종료하는 것을 요구한다. 하지만 kill은 그 명칭과는 조금 다르게 종료와 무관한 메시지를 보낼 때도 사용한다. kill 명령어는 내부적으로 kill()이란 시스템 콜을 사용하여 구현하고, 프로세스 식별자(PID)로 지시한 프로세스와 프로세스 그룹 식별자(PGID)로 지시한 프로세스 그룹에 시그널을 보낸다. kill은 예전부터 독립적인 유틸리티로 제공되었으나 많은 프로그램은 약간 다른 형태의 kill 명령어를 가지고 있다.


사용자가 일반적으로 가장 많이 사용하는 시그널은 SIGTERM과 SIGKILL인데, kill은 이 외에도 서로 다른 다양한 종류의 시그널을 보내는 것이 가능하다. 기본적으로 보내지는 시그널은 SIGTERM이다. 이 시그널을 받은 프로세스는 프로그램을 종료하기 전에 프로그램을 종료하는 처리(환경설정을 파일에 기록한다던지...)를 수행하는 것이 가능하다.


프로세스는 SIGKILL과 SIGSTOP을 제외한 모든 시그널에 대해서 시그널에 대한 처리를 하는 별도의 루틴을 만들 수 있다. 이것은 프로세스가 시그널을 받았을 때 어떤 특별한 처리를 하기 위함이다. 예외적으로, 프로세스는 SIGKILL과 SIGSTOP에 대한 처리를 할 수 없도록 되어있다. SIGKILL은 프로세스를 강제 종료하는 명령이고 SIGSTOP은 SIGCONT 시그널을 받을 때까지 프로그램 실행을 정지시키는 명령이다.


유닉스는 권한없는 사용자가 프로세스를 종료하는 것을 방지하기 위해 보안 기능을 제공하고 있다. 기본적으로는 어떤 프로세스가 다른 프로세스로 시그널을 보낼 때, 시그널을 보내는 프로세스의 소유자가 시그널을 받는 프로세스의 소유자와 같은지, 최고 관리자인지 확인하게 된다.


사용 가능한 시그널은 고유한 명칭이 있고 특정한 숫자와 대응되어 있다. 유닉스의 설계에 따라서 시그널과 숫자의 대응이 다른 것은 주의할 필요가 있다. SIGTERM은 많은 경우 15이고, SIGKILL은 많은 경우 9이다.


일반적으로 해당 Process에 문제가 있어서 다시 시작하고자 할 때에는 SIGHUP, SIGTERM, SIGKILL의 순서로 각각 시도하길 바란다.


아래 명령어로 전체 시그널의 리스트를 볼 수 있다. 


$ kill -l


pi@raspberrypi:~/smartfarm $ kill -l


 1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP

 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1

11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM

16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP

21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ

26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR

31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3

38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8

43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7

58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2

63) SIGRTMAX-1  64) SIGRTMAX


참고 사이트 


http://studio1977.kr/Kill

http://www.joinc.co.kr/w/Site/system_programing/Book_LSP/ch06_Signal 



예제 소스코드


 #include <signal.h> //Signal 사용 헤더파일
#include <unistd.h>
#include <stdio.h> 
#include <string.h> 
#include <errno.h>
#include <stdlib.h> //exit() 사용 헤더파일

#include <wiringPi.h>

#define FAN	22 // BCM_GPIO 6

void sig_handler(int signo); // 마지막 종료 함수

int main (void)
{
	signal(SIGTERM, (void *)sig_handler);	//시그널 핸들러 함수
	
	if (wiringPiSetup () == -1)
	{
		fprintf(stdout, "Unable to start wiringPi: %s\n", strerror(errno));
		return 1 ;
	}

	pinMode (FAN, OUTPUT) ;

	for (;;)
	{
		//printf("here - FAN on\n");
		digitalWrite (FAN, 1) ; // On		
	}
	return 0 ;
}

void sig_handler(int signo)
{
    printf("process stop\n");
	digitalWrite (FAN, 0) ; // Off
	
	exit(0);
}
 







반응형