본문 바로가기

개발자/Raspberry Pi

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

반응형




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


라즈베리 파이를 이용해서 개발할때 


보통 GPOI 로 출력을 보내 LED를 켠다든지, 모터를 작동시키는 경우 반복적으로 테스트 하는데 중간에 ctrl-c 로 강제로 프로세스를 중지하고 나올 경우가 있다.


이런 경우 보통 라즈베리 파이 GPIO 에는 이전에 신호가 계속 들어와 있는 관계로 프로그램은 종료 되었는데 LED 는 계속 ON 상태고, 모터 같은 액츄에이터 들은 계속 돌고 있는 약간은 황당한 일이 일어난다.


이러한 애매한 상황이 일어나지 않기 위해 시스템이 보내는 시그널의 하나인 INTSIG 를 사용하는 방법을 알아보자.


액츄에이터 제어 실습시 보통 실험을 종료할 경우 ctrl-c 를 눌러 종료하게 되는데, 이 때 GPIO 신호는 그대로 실습때의 상태를 유지하게 된다. 즉, 전원이 켠 상태나 전등이 ON 상태로 프로그램을 종료해도 전원이 공급되고, 전등은 ON 상태로 남아있게 되는데 이렇게 종료되는 것을 방지하는 방법을 설명한다.


컴퓨터 시스템 상에서 발생할수 있는 상황도 여러가지가 있다. 이는 OS에 따라 다르게 설정된다. OS에서 어떠한 시그널을 지원하는 지는 kill 명령을 이용해서 알아볼수 있다. 아래는 필자의 리눅스 박스로써 kernel 2.4.3 에서 지원하는 시그널을 캡쳐한 화면이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ 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     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      32) SIGRTMIN    33) SIGRTMIN+1
34) SIGRTMIN+2  35) SIGRTMIN+3  36) SIGRTMIN+4  37) SIGRTMIN+5
38) SIGRTMIN+6  39) SIGRTMIN+7  40) SIGRTMIN+8  41) SIGRTMIN+9
42) SIGRTMIN+10 43) SIGRTMIN+11 44) SIGRTMIN+12 45) SIGRTMIN+13
46) SIGRTMIN+14 47) SIGRTMIN+15 48) SIGRTMAX-15 49) SIGRTMAX-14
50) SIGRTMAX-13 51) SIGRTMAX-12 52) SIGRTMAX-11 53) SIGRTMAX-10
54) SIGRTMAX-9  55) SIGRTMAX-8  56) SIGRTMAX-7  57) SIGRTMAX-6
58) SIGRTMAX-5  59) SIGRTMAX-4  60) SIGRTMAX-3  61) SIGRTMAX-2
62) SIGRTMAX-1  63) SIGRTMAX
cs


보통 32번까지의 시그널은 대부분의 UNIX 계열에서 비슷한 값을 보여주며, 33번부터 62번까지는 아마도 OS 마다 약간식의 차이를 보여줄것이다. 


각각의 시그널은 int 형의 숫자로 표시되는데, 시그널 번호에 따라서 다른 상황을 나타낸다. 

 Ctrl-c 를 누른 순간 SIGINT신호가 발생되는데 우리는 이 신호를 이용하여 정리를 해주고 나오면 된다.예제로 살펴본다. (예제: sigint.c)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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); // 마지막 종료 함수 ctlr-C 로 종료
 
int main (void)
{
    signal(SIGINT, (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)  //마지막 처리를 위한 signal 핸들러 함수 모두 OFF
{
    printf("process stop\n");
    digitalWrite (FAN, 0) ; // Off
    
    exit(0);
 
cs


이 코드에서 함수 sig_handler(int signo) 부분에 작동하는 GPIO 핀을 동작하지 않게 하거나 초기 상태로 두는 코드를 넣으면 될것이다.











반응형

더욱 좋은 정보를 제공하겠습니다.~ ^^