Signal Conceps
- 프로그램 수행 중 여러가지 이벤트가 발생
- floating point error
- 파워가 꺼지기 직전 경고
- 알람기능
- child process가 종료됐을 경우 parent로 알림
- Ctrl + C : 정해진 명령
- Ctrl + Z : 중단
- 이러한 이벤트들을 signal이라고 부름
- 비동기적인 이벤트를 프로세스에 알려줌 - ex) Ctrl + C를 누를 경우 알림을 줘야하는데 언제 주는지는 정확히 모름
- Signal 발생시 프로세스에게 전달이 되고 다양한 액션을 취함
- 무시
- signal을 catch : 적합한 함수를 호출해줌 -> signal handler
- 함수를 명시적으로 등록하지 않았더라도 default된 액션을 취함
- 무시
- 프로세스 종료
- 프로세스 종료 후 core dump라는 파일(상태값 - 레지스터 값, 메모리의 값)을 만듦 -> 프로그램을 디버그할 때 사용가능
- 프로세스를 중지(일시정지)시킴
- 만약 정지되어 있다면 다시 수행을 재개
Linux Signals
- signal.h라는 헤더파일에 int형으로 저장되어 있으나 Name형식으로 정의되어 있음
- SIGALRM : 알람을 울려줌 -> 14번, default는 term(terminated - 프로세스 종료)
- SIGCHLD : child process가 종료 되었을 때 부모 프로세스가 받는 것 -> default는 무시
- SIGCONT : 프로세스가 중단되어 있을 때 이 시그널을 받으면 다시 재개 -> default는 cont(재개)
- SIGKILL : 이 시그널을 받으면 반드시 죽음
- SIGPWR : 시스템의 파워가 곧 꺼질 것이라는 알림
- SIGSEGV : 잘못된 메모리의 접근 시 알림 -> default는 core(특정 상태를 파일에 dump) - 이 파일로 분석 가능
- SIGSTOP : Ctrl + Z와 같은 기능 -> 프로세스를 잠시 정지
- SIGTERM : process termination -> SIGKILL과는 다르게 signal handler로 처리가능
- signal(2)/signal(7)에 많은 정보가 있음
Dispatching Signals: kill(2) and raise(3)
- signal을 특정 프로세스에 보낸다는 의미
- kill(2) and raise(3)
- kill(2)
- pid라는 프로세스에게 지정한 signo을 보내는 것 - ex) pid = 100이라는 프로세스에 SIGTERM을 보냄
- pid > 0 : 해당하는 pid에 시그널을 보냄
- pid = 0 : 0으로 설정하면 signal을 보내는 프로세스와 같은 그룹ID를 가지는 모든 프로세스에게 지정한 signal을 보냄 -> broadcast, multi-cast
- pid<-1,pid = -1
- pid 가 -1 이면, 1번 프로세스를 제외한 모든 프로세스에서 시그널을 보냄
- pid 가 -1 보다 작으면, -pid 프로세스가 포함된 모든 그룹의 프로세스에게 시그널을 보냄
- raise(3)
- kill(getpid(),signo)와 같은 역할 -> 자기 자신에게 시그널을 보냄
signal delivery and handler execution
- 프로그램이 수행중에 언제 외부의 signal이 도착할지 알 수 없음
- 프로그램이 실행되는 중간에 signal이 도착하면 프로그램은 잠시 수행을 중단하고 signal handler라는 함수에 감
- signal에 해당하는 일을 처리 후 return
- signal을 받았던 장소로 돌아와서 명령 수행
- 어느 시점에 오는지 정확히 모르므로 비동기적인 처리를 해야함
setting up a Signal Handler: signal(2)
- signal handler를 등록하는 방법
- signal(2)
- signum - 지정한 시그널 번호/handler - handler 등록 -> type은 지정한 함수에 대한 fucntion pointer
- sighandler_t : return값 -> 예전에 이미 등록된 함수 handler의 function pointer를 반환
- SIG_IGN : 지정한 시그널을 무시
- SIG_DFL : default action
- 위 둘 다 아니라면 명시적으로 signal handler를 등록
- 요즘에는 signal(2)이라는 함수보다 sigaction(2)이라는 함수를 많이 사용
- 예제
-
SIGINT : signum/ ouch : 함수 -> 지정
-
1초 마다 반복
-
만약 SIGINT가 Ctrl + C라면 프로그램 실행 중 Ctrl + C를 하면 ouch 함수를 수행
sigaction(2)
- signal함수와 같은 역할이나 좀 더 정밀한 작업에 사용됨 -> thread나 real-time signal 등
- signum에 해당하는 sigaction이라는 structer에 저장
- 첫 번째가 handler부분 - signal이 발생했을 때 실행
- sa_mask : signal이 동작하는 동안에 이곳에 저장된 signal들이 오면 막아줌
- 현재 리눅스에서는 sigaction으로 구현되어 있으므로 간단한 경우를 제외하고는 이 시스템 콜을 사용할 것
signal sets
- 여러 시그널을 한 세트로 지정
- sigemptyset : set에 대한 pointer를 주면 비워버림
- sigfillset : 전체 집합으로 설정 - 전부 1로
- sigaddset : 지정된 signum을 추가
- sigdelset : 지정된 signum을 제거
- sigismember : signum이 포함되어 있는지 알려줌
- 예제
- sigaction을 사용
- sigemptyset으로 비움
- flag를 0또는 NULL으로 지정
- ouch라는 handler등록
- SIGINT가 왔을 때 sa에 지정된 handler를 수행
- sa_mask를 비웠기 때문에 아무런 signal도 막지 않고 받아들인다는 뜻
- sigaction의 세 번째 파라미터는 입력된 handler가 등록이 되어있다 하면 예전의 handler를 리턴
- while로 반복하며 Ctrl + C를 누르면 지정한 핸들러가 호출됨
Signal Mask
- 시그널이 오는 것을 막을 수 있음
- how에 대한 action을 취함/set
- SIG_BLOCK : set에 지정한 시그널들을 이미 블록된 signal들에 합산하여 막아줌
- SIG_UNBLOCK : set에 지정된 시그널들은 signal이 전달 될 수 있도록 설정
- SIG_SETMASK : set에 지정된 시그널들을 block시켜줌
- sigpending : 시그널이 block되어 대기하는 상태 -> 이러한 시그널들이 무엇이 있는지 파악하여 set에 반환
- 예제
- block_set을 비움
- SIGINT를 추가 -> 비운 후 추가 했으므로 SIGINT만 설정
- sigprocmask : 현재 blocking되어있는 signal set에 block_set을 추가/이전에 지정된 signal set들을 prev_set에 리턴
- 아래 함수가 수행되는동안 Ctrl+C를 눌러도 block되어 (pending)대기 -> 여러번 누르더라도 1개만 저장 됨
- sigprocmask : 이전 blocking set들을 다시 되돌려 놓음 -> SIGINT가 없을 때의 상태
- 이 후 바로 이전에 눌렸던 pending된 signal이 바로 전달되어 default action인 term을 실행
- for루프에 가기전에 프로세스가 끝나버림
Timers, and Sleeping
- 일정 시간이 경과하면 알림
- second만큼 지나면 SIGALRM이 프로세스에 도착
- 만약 seconds=0이면 setting해놓은 알람을 canceled
- 알람은 프로세스에서 딱 1개만 설정
- POSIX interval timers가 Unix에 추가됨 -> 여러개의 timer setting가능
- 예제
- handler등록
- sigaction : SIGALRM에 handler 등록
- alarm(5) : 5초로 등록
- 반복문이 진행되다가 5초가 지나면 지정된 함수를 실행
- waiting = 0이므로 반복문 종료
sleep(3), nanosleep(2)
- 지정된 시간동안 프로그램 수행을 중단시킴
- seconds동안 정지
- msec, nsec로 정밀하게 조정가능 : nanosleep -> timespec을 받음
- tv_sec은 second, tv_nsec은 nanosecond
- 두 번째 파라미터 rem : sleep중 인터럽트를 받아 종료 되었을 때, 남은 초를 반환
'임베디드SW공학' 카테고리의 다른 글
[13주차]POSIX Threads(2) (0) | 2018.12.02 |
---|---|
[12주차]POSIX Threads(1) (0) | 2018.12.01 |
[10주차]리눅스 시스템 프로그래밍:Processes (0) | 2018.11.19 |
[9주차]시스템 콜 파일(2) - 디렉토리 (0) | 2018.11.17 |
[8주차]리눅스시스템 프로그래밍: File I/O (0) | 2018.11.11 |