이번 포스팅은 8장 시그널에 대하여 알아보도록 하겠습니다.
● 시그널(Signal)
- 시그널은 소프트웨어 인터럽트이다.
- 시그널은 비동기적으로 프로세스에 신호를 보낸다.
시그널은 다음과 같은 세 가지 경우에 발생한다.
1. 0으로 나누기처럼 프로그램에서 예외적인 상황이 일어나는 경우
2. 프로세스가 kill() 함수와 같이 시그널을 보낼 수 있는 함수를 사용해 다른 프로세스에 시그널을 보내는 경우
3. 사용자가 ctrl+c 같은 인터럽트 키를 입력한 경우
● 시그널 보내는 함수
- kill(pid, sig) : 시그널을 임의로 보내기 위해서는 kill함수를 사용한다.
매개변수로 시그널을 보낼 프로세스의 pid, 보낼 시그널 번호를 지정한다.
pid가 0보다 큰 수 : pid로 지정한 프로세스에 시그널을 보낸다.
pid가 -1이 아닌 음수 : 프로세스 그룹 ID가 pid의 절댓값인 프로세스 그룹에 속하고 시그널을 보낼 권한이 있는 모든 프로세스에 시그널을 보낸다.
pid가 0 : 특별한 프로세스(스케줄러 등)를 제외하고 프로세스 그룹 ID가 시그널을 보내는 프로세스의 프로세스 그룹 ID와 같은 모든 프로세스에 시그널을 보낸다.
● 시그널 핸들러
- Signal(signum, handler) : 어떤 시그널을 받을 때 동작하는 방식을 지정하는 방법으로 signal함수를 사용한다.
매개변수로는 처리할 시그널 번호(매크로)와 handler에 관한 함수명을 지정한다.
● 알람 시그널
- alarm(seconds) : 일정 시간이 지난 후 시그널을 발생시키는 방법으로 alarm함수를 사용한다.
매개변수로는 시그널발생을 지연시킬 초단위 값을 지정한다.
● 시그널 처리 방법
1. 기본 정해진 동작 수행
2. 시그널 무시
3. 지정된 함수 호출
4. 시그널 블록
● 시그널 기다리기
pause(void) : 시그널이 도착하기를 기다릴 때 사용할 수 있는 함수로써 pause함수를 사용한다.
사용되는 매개변수는 없다.
● 시그널 예제 // fork() 3번, kill 사용
#include <stdio.h> #include <stdlib.h> #define max 3 // 시그널 핸들러 작성 void sigHandler(int signo) { printf("%d\n", getpid()); exit(1); } int main(){ int child = 0; pid_t pid, pids[max]; // 자식 프로세스 3개 생성 while(child<3) { pid = fork(); pids[child] = pid; // 자식 프로세스 중 3개값만 사용하도록 pid배열에 저장 if(pid == -1) exit(0); else if(pid == 0) { // 자식 프로세스는 시그널을 무한정 대기하도록 함 signal(SIGINT, sigHandler); pause(); } else { printf("child pid : %d\n", pids[child]); } child++; } int status; // 3초 기다린 후 자식 프로세스들에게 kill함수를 사용하여 시그널 전송 sleep(3); for(int i =0; i<3; i++) { kill(pids[i],SIGINT); } wait(&status); return 0; } |
위 예제코드는 부모 프로세스에서 3개의 자식 프로세스 생성 후 부모 프로세스에서 3초후 자식 프로세스에게 SIGINT 신호를 보내는 내용입니다.
위의 코드에서 fork()를 3회 진행하여 총 8개의 프로세스를 생성하지만 pids[3] 배열을 이용하여 3개의 자식 프로세스의 pid를 저장하고 이를 이용하여 signal을 전송하고 있습니다.
● 시그널 예제2 //alarm 사용
#include <stdio.h> #include <signal.h> #include <sys/types.h> int i= 0; //타이머를 위한 전역변수 지정 // 알람 핸들러 지정 void myalarm() { printf("My Message No.%d\n", i); i++; } void main() { pid_t pid; pid = fork(); if(pid == 0) { signal(SIGALRM, myalarm); // 시그널 선언 for(int j =0; j <=62; j++){ //반복문을 돌면서 alarm(1)을 통해 1초 간격으로 시그널 발생 alarm(1); pause(); } exit(0); } sleep(60); kill(pid, SIGINT); return 0; } |
위 예제코드는 alarm이라는 시그널을 통해서 60초 타이머 프로그램을 만드는 예제입니다.
본 글은 공부를 위한 참고용 작성 포스팅입니다.
'CS > 시스템 프로그래밍' 카테고리의 다른 글
시스템 V IPC (System V) 2 -Infinite (0) | 2022.06.21 |
---|---|
시스템 V IPC (System V) 1 -Infinite (0) | 2022.06.21 |
파이프(PIPE) -Infinite (0) | 2022.06.20 |
쓰레드(Thread) -Infinite (0) | 2022.06.20 |
프로세스 생성과 실행 -Infinite (1) | 2022.06.20 |
개발 기술 블로그, Dev
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!