Signal

- Signal 전달
- Kernel → user
- user → user
- signal은 언제 처리가 되는가?
- signal이 process에 언제 전달이 되는가?
- PCB에 대기하고 있다가 signal table에 mark 되었을 때
- pending signal : 아직 handle되지 않은 signal
- signal blocking : user에 의해 일시적으로 signal handling이 block 된 상황
User 관점
- user program → signal(event) 발생 → user program interrupt → signal handler 작동(user mode에서 동작) → exit or restart
Kernel 관점
- event 발생 → PCB 내부에 있는 signal table에 event를 marking → signal handler 호출 → user mode로 복귀
- OS의 관리
Signal Handling
1. default handler(SIG_DFL)
- 일반적인 error 상황에 사용
- exit / core-dump&exit 처리
2. ignore signal(SIG_IGN)
- signal을 무시한다.
- SIGKILL / SIGSTOP은 절대 무시할 수 없다.
3. user defined signal handler
- function 등을 이용해서 signal을 처리하는 것
주로 사용하는 Signal 종류
Signal name | Reason of a Signal | value | Default handler |
---|
SIGABRT | program 중단 | 6 | Core-dump & exit |
SIGALRM | Timer alarm 기능 | 14 | Exit |
SIGCHLD | child process 죽었을 때 | 17 | Restart / Ignore |
SIGCONT | 멈춘 process 재시작 | 18 | Restart / Ignore |
SIGILL | 정상 instruction이 아닐 때 | 4 | Core-dump & exit |
SIGHUP | session이 끊어졌을 때 | 1 | Exit |
SIGINT | ^C | 2 | Exit |
SIGKILL | 즉시 현재 process 종료 | 9 | Exit |
SIGPIPE | pipe에 reader가 없는데 write 할 때 | 13 | Exit |
SIGQUIT | ^Z | 3 | Core-dump & exit |
SIGSEGV | memory 접근에 문제가 있을 때 (pointer 등..) | 11 | Core-dump & exit |
SIGSTOP | debugger와 같은 것을 멈출 때 | 19 | Stop |
SIGUSR1 | user가 정의하는 signal1 | 10 | Exit |
SIGUSR2 | user가 정의하는 signal2 | 12 | Exit |
- system마다 signal number가 다를 수 있으므로 signal number(value)보다는 signal name을 이용하도록 하자.
Signal function
Signal()
#include <signal.h>
typedef void (*sighandler_t)(int); // void function pointer
sighandler_t signal(int signum, sighandler_t handler);
- user가 정의하는 signal handler 함수
- signum : signal number
- handler : signum에 해당하는 signal이 발생했을 때 handler 적용을 할 function
- return : 성공 시 old signal handler 주소 / 실패 시 SIG_ERR
- signal handler는 1회용으로, 한 번만 쓰이고 default handler로 reset된다.
- 계속 자신의 handler로 사용하기 위해서는 매번 초기화를 해야한다.
kill()
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
- process에게 signal을 send하는 함수
- pid : process id
- pid > 0 : 해당 process에게만 send
- pid = 0 : process group 모두에게 send
- pid = -1 : init을 제외한 생성된 모든 process에게 send
- sig : signal number
- return : 성공 시 0 / 실패 시 -1
raise()
#include <signal.h>
int raise(int sig);
- 자기 자신에게 signal을 보낸다.
- kill(getpid(), sig)와 같이 사용할 수도 있다.
- return : 성공 시 0 / 실패 시 -1
alarm()
#include <unistd.h>
unsigned alarm(unsigned sec);
- 일정시간(sec) 뒤에 SIGALARM을 send한다.
- return
- 처음 alarm() : 0
- 이전 alarm()이 존재하고 끝나지 않았을 때 : 이전 alarm의 남은 시간
abort()
#include <stdlib.h>
void abort(void);
- process를 강제 종료할 때 사용
- SIGABRT가 send 되고, come dump / exit이 된다.
pause
#include <unistd.h>
int pause(void);
sigprocmask() & mask structure 조작
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oset);
// clear a signal mask set structure, NOT real mask
int sigemptyset(sigset_t *set);
// set all signal set mask structure
int sigfillset(sigset_t *set);
// add a signoto a given signal set mask structure
int sigaddset(sigset_t *set, int signo);
// delete a signofrom a given signal set mask structure
int sigdelset(sigset_t *set, int signo);
// for the above functions,
// return 0 if OK, -1 on an error
// ask if a signal is set in a signal mask set structure
int sigismember(sigset_t *set, int signo);
// return 1 if the signo is int the set, otherwise 0.
// -1 on an error
- how : blocking / unblocking
- SIG_BLOCK : add → block
- SIG_UNBLOCK : remove → unblock
- SIG_SETMASK : replace
- set : signal set(bit-vector)
- oset : old set
sigpending()
#include <signal.h>
int sigpending(sigset_t *set);
- pending signal set을 get
- return : 성공 시 0 / 실패 시 -1
sigsuspend()
#include <signal.h>
int sigsuspend(const sigset_t *set);
- mask와 pause를 동시에 set하는 automic operation이다.
sleep()
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
unsigned int nanosleep(unsigned int nano-seconds);
unsigned int usleep(unsigned int miocro-seconds);
- seconds 시간만큼 wait/block
- wakeup 후 남은 시간을 return
System call & Signal
- 만약 system call을 처리하고 있을 때 signal이 전달이 되는 상황에는 어떻게 해야하는가?
1) TASK_UNINTURRUPTIBLE
- block한 뒤 system call을 처리한 뒤 signal을 처리
2) TASK_INTURRUPTIBLE
- signal handler를 처리한 뒤 system call을 처리