결론적부터 말하자면 리눅스에서 시스템 메세지 발생하는 것 중에 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://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);
}
'개발자 > Raspberry Pi' 카테고리의 다른 글
1월 25일 K-ICT 디바이스랩 판교에서 삼성 ARTIK 소개 (0) | 2017.01.26 |
---|---|
라즈베리파이 공식 7인치 터치스크린 (Raspberry-Pi Touch Display) (Rev 1.1) (0) | 2017.01.17 |
라즈베리 파이 LoRa 통신 모듈 테스트 남은 일들 (2) | 2016.12.20 |
ctrl-c 프로세스 종료시 주의할 점과 SIGINT 시그널 사용법 (0) | 2016.12.08 |
랜케이블 하나로 가장 빠르게 라즈베리파이와 접속하는 방법 (1) | 2016.11.30 |
라즈베리 파이로 DHT22 온도 습도 센서 사용하기 C 언어 (6) | 2016.10.24 |
라즈베리파이 DHT11 온도 습도 센서 사용하기, LCD 에 온도와 습도를 출력 (17) | 2016.10.24 |
라즈베리파이 LCD 1602 사용하기 16x2 LCD Hello World using C (2) | 2016.10.20 |
더욱 좋은 정보를 제공하겠습니다.~ ^^