Task 통신및동기화 : 시그널 (Signal) Chapter #10
Cooperating Processes Signal 개요 Signal 처리 Signal 전송 타이머처리 강의목차 Unix System Programming 2
Cooperating Processes (1) Independent process cannot affect or be affected by the execution of another process. Cooperating process can affect or be affected by the execution of another process Advantages of process cooperation Information sharing Computation speed-up Modularity Convenience Unix System Programming 3
Cooperating Processes (2) Cooperating process 적용 producer and consumer shared resource parallel matrix processing mobile computing Unix System Programming 4
Cooperating Processes (3) Interprocess Communication & Synchronization Producer : Consumer : : while (1) { /* produce an item */ while (counter == BUFFER_SIZE); /* do nothing */ buffer[in] = nextproduced; in = (in+1) % BUFFER_SIZE; counter++; } : : while (1) { /* consume an item */ while (counter == 0); /* do nothing */ nextconsumed = buffer[out]; out = (out+1) % BUFFER_SIZE; counter--; } : 공유에따른동기화문제가발생 Unix System Programming 5
Cooperating Processes (4) Interface for Cooperating processes at the same sites Signal Semaphore Pipe, FIFO System V IPC (InterProcess Communication) message passing shared memory STREAM socket Interface for Cooperating processes at the different sites Socket RPC RMI, DCOM, CORBA, Unix System Programming 6
시그널 (signal) Signal (1) 비동기적인사건 (asynchronous event) 의발생을프로세스에게알리는메커니즘 Facility for handling exceptional conditions Software interrupts to processes 가장기본적인유형의프로세스간의통신메커니즘 시그널전송 커널이프로세스에게 프로세스간에 Unix System Programming 7
Signal (2) 시그널의종류 <signal.h> 에서정의 SIGKILL, SIGINT, SIGBUS, SIGUSR1,. ( 최대64) 대표적인시그널 SIGHUP(1) 제어터미널이 hangup되었는지를검출 SIGINT(2) 키보드에서발생한인터럽트 SIGQUIT(3) 키보드에의한중지 SIGKILL(9) 프로세스강제종료 SIGUSR1(10) 사용자정수시그널 1 SIGSEGV(11) 세그멘테이션폴트에러 SIGUSR2(12) 사용자정수시그널 2 SIGALRM(14) 타이머알람시그널 SIGTERM(15) 소프트웨어종료 SIGCHLD(17) 자식프로세스의정지또는종료를부모프로세스에게알림 Unix System Programming 8
Signal (3) 태스크의시그널처리방법 태스크종료 (exit, abort) 대부분의시그널은시그널수신시에프로세스가정상종료 (normal termination) 한다 SIGABRT, SIGBUS, SIGSEGV, SIGQUIT, SIGILL, SIGTRAP, SIGSYS, SIGXCPU, SIGXFSZ, SIGFPE 시그널은비정상종료 (abnormal termination) 을발생시킴 abort() SIGABRT 발생, core dump 디버깅에사용 시그널무시 (ignore) 태스크수행중지 (stop) 사용자수준시그널처리함수 (user level catch function) 수행 Unix System Programming 9
Linux Signal (1) Signals for terminating processes SIGHUP This signal is sent to the controlling process associated with a controlling terminal if a disconnect is detected by the terminal interface. This signal is also generated if the session leader terminates. In this case the signal is sent to each process in the foreground process group. This signal is commonly used to notify daemon processes to reread their configuration files. The reason SIGHUP is chosen for this is because a daemon should not have a controlling terminal and would normally never receive this signal. default action: termination Unix System Programming 10
Linux Signal (2) Signals for terminating processes SIGINT sending of the interrupt character from the terminal [CTRL-C] Termination SIGQUIT sending of the quit character from the terminal [CTRL- ] Termination with core SIGABRT, SIGIOT abnormal termination (abort( )), hardware fault Termination SIGKILL irrevocable termination signal Termination SIGTERM default signal sent out by the kill command Termination Unix System Programming 11
Linux Signal (3) Signals triggered by a particular physical circumstance SIGILL illegal instruction / termination SIGTRAP breakpoint in a program (system call ptrace) termination with core SIGBUS bus error / termination SIGFPE arithmetic error (floating point exception) / termination SIGSEGV memory address invalid / termination with core SIGSTKFLT Maths co-processor stack overflow (only in the Intel architecture) termination Unix System Programming 12
Linux Signal (4) Signals available for use by the programmer SIGUSR1, SIGUSR2 Termination Signal generated when a pipe is closed SIGPIPE pipe without reader / termination Linked to resources SIGXCPU CPU time limit exceeded / termination SIGXFSZ file size limit exceeded / termination Unix System Programming 13
Linux Signal (5) Suspending or resuming SIGCHLD, SIGCLD termination of child process / ignore SIGCONT repetition in the foreground or background of the process resume execution if it is stopped SIGSTOP suspension of process / suspension (non-changeable) SIGTSTP sending out of suspension character from the terminal [CTRL-Z] Suspension SIGTTIN terminal read for a background process / suspension SIGTTOU writing to a terminal for a background process / suspension Unix System Programming 14
Management of alarms Linux Signal (6) SIGALRM end of timer ITIMER_REAL or alarm() / termination SIGVTALRM end of timer ITIMER_VIRTUAL / termination SIGPROF end of timer ITIMER_PROF / termination Unix System Programming 15
Linux Signal (7) Management of inputs and outputs SIGWINCH change of window size (used by X11) / ignore SIGIO, SIGPOLL data available for an input/output / termination SIGURG urgent data for sockets / ignore Fault with the power supply SIGPWR, SIGINFO power fault / termination Unix System Programming 16
Signal 생성 터미널에서특수키를누르는경우 e.g: ^-C SIGINT 하드웨어의오류 0 으로나눈경우, 잘못된메모리를참조하는경우등 kill 함수의호출 특정프로세스나프로세스그룹에게원하는시그널을발생 / 전달한다. 대상프로세스에대한권한이있어야한다. kill 명령의실행 내부적으로 kill 함수를호출한다. 소프트웨어적조건 네트워크에서의데이터오류 (SIGURG), 파이프작업에서의오류 (SIGPIPE), 알람시계의종료 (SIGALRM) 등 Unix System Programming 17
시그널의전달 Signal 전달 발생된시그널이수신되어정해진방법대로처리되는것 지연 (pending) : 발생된시그널의전달되지못한상태 시그널의블록킹 (blocking) 블록킹이해제되거나무시하도록변경될때까지지연된상태로남는다. 시그널마스크 (signal mask) : 블록킹될시그널집합지정 Unix System Programming 18
Signal 처리 시그널을받은프로세스의행동 ( 세가지처리 ) Default action (SIG_DFL) 특별한처리방법을선택하지않은경우 대부분시그널의기본처리방법은프로세스를종료시킴 Ignore the signal (SIG_IGN) SIGKILL과 SIGSTOP 시그널을제외한모든시그널을무시할수있다. 하드웨어오류에의해발생한시그널에대해서는주의해야한다. Catch the signal 시그널이발생하면미리등록된함수 (signal handler) 가수행 SIGKILL and SIGSTOP cannot be caught or ignored Unix System Programming 19
Signal 관련시스템콜 (1) 시그널집합 (Signal Set) 설정 시그널리스트생성및설정 #include <signal.h> /* 초기화 */ int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); /* 조작 */ int sigaddset(sigset_t *set, int signo); int sigdelset(sigset_t *set, int signo); Unix System Programming 20
Signal 관련시스템콜 (2) 시그널집합 (Signal Set) 설정 ( 계속 ) #include <signal.h> sigset_tmask1, mask2;... /* 빈집합을생성한다. */ sigemptyset(&mask1); /* 시그널을추가한다. */ sigaddset(&mask1, SIGINT); sigaddset(&mask1, SIGQUIT); /* 완전히차있는집합을생성한다. */ sigfillset(&mask2); /* 시그널을제거한다 */ sigdelset(&mask2, SIGCHLD);... Unix System Programming 21
Signal 관련시스템콜 (3) 시그널처리함수설정 : signal() #include <signal.h> void (*signal(int signum, void(*handler)(int)))(int) /* int signum : 시그널번호 */ /* void (*handler)(int) : 시그널처리함수 */ /* 정상종료하면 signum 에대한이전의 handler 값을반환하고, 에러가발생한경우에서는 SIG_ERR 를반환한다. 외부변수 errno 에에러를나타내는값을설정한다 */ 첫번째인자 signum에서지정한번호의시그널에새로운시그널처리함수 handler를지정한다 SIGKILL(9), SIGSTOP(19) 시그널에대해서는시그널처리함수를지정할수없다 Unix System Programming 22
Signal 관련시스템콜 (4) 시그널처리함수설정 : signal() ( 계속 ) signal() 함수재정의 #include <signal.h> typedef void (*sighandler_t)(int) #define SIG_ERR ((sighandler_t) -1) sighandler_t signal(int signum, sighandler_t handler) 미리정의된시그널처리함수 SIG_DFL 디폴트처리동작을지정 SIG_IGN 시그널을무시 SIGKILL, SIGSTOP 시그널은무시할수없다 Unix System Programming 23
Signal 관련시스템콜 (5) 시그널처리함수설정 : signal() ( 계속 ) 리눅스운영체제에서는시그널이발생할때마다디폴트동작으로되돌아간다 signal() 시스템콜을통해시그널처리함수를지정하여도시그널처리함수를종료하고복귀하면 SIG_DFL 값이지정된다 시그널처리함수를반복적으로지정하여야하는경우에는시그널처리함수에서다시 signal() 시스템콜를이용하여시그널처리함수를지정하여야한다 Unix System Programming 24
Signal 관련시스템콜 (6) 시그널처리함수설정 : signal() ( 계속 ) 예제프로그램 #1: 교재 pp.315~315, setsigint.c 예제프로그램 #2: 교재 pp.318~320, ctohex_sig.c 예제프로그램 #3: 교재 pp.321~324, parent_sig.c Unix System Programming 25
Signal 관련시스템콜 (7) 시그널처리함수설정 : sigaction() #include <signal.h> int sigaction(int signo, const struct sigaction *act, struct sigaction *oact) /* signo: signal to be processed */ /* struct sigaction{ void (*sa_handler)(int); /*the action to be taken */ sigset_t sa_mask; /* 시그널을처리하는동안봉쇄할시그널 */ int sa_flags; /* 시그널의형태에영향을미칠플래그들 */ void (*sa_sigaction)(int, siginfo_t*, void *)); /* 시그널핸들러에대한포인터 */ } */ /* the first field can hold SIG_DFL, SIG_IGN */ Unix System Programming 26
Signal 관련시스템콜 (8) 시그널처리함수설정 : sigaction() ( 계속 ) 예제프로그램 : /* sigex--sigaction 이어떻게동작하는지보인다 */ #include <signal.h> int main(void) { static struct sigaction act; /* catchint 를선언한다. 후에핸들러로사용된다. */ void catchint(int); /* SIGINT 를수신했을때취해질행동을지정한다. */ act.sa_handler= catchint; /* 완전히찬마스크를하나생성한다. */ sigfillset(&(act.sa_mask)); /* sigaction호출전에는, SIGINT가프로세스를종료시킨다 ( 디폴트행동 ) */ Unix System Programming 27
Signal 관련시스템콜 (9) } sigaction(sigint, &act, NULL); /* SIGINT 를수신하면제어가 catchint 로전달될것이다 */ printf("sleep call #1\n"); sleep (1); printf("sleep call #2\n"); sleep (1); printf("sleep call #3\n"); sleep (1); printf("sleep call #4\n"); sleep (1); printf("exiting\n"); exit (0); /* SIGINT를처리하는간단한함수 */ void catchint(intsigno) { printf("\ncatchint: signo=%d\n", signo); printf("catchint: returning\n\n"); } Unix System Programming 28
Signal 관련시스템콜 (10) 시그널처리함수설정 : sigaction() ( 계속 ) SIGINT 무시 act.sa_handler= SIG_IGN sigaction(sigint, &act, NULL); 인터럽트키의 enable act.sa_handler= SIG_DFL; sigaction(sigint, &act, NULL); 여러개의시그널을동시에무시 act.sa_handler= SIG_IGN; sigaction(sigint, &act, NULL); sigaction(sigquit, &act, NULL); Unix System Programming 29
Signal 관련시스템콜 (11) 시그널처리함수설정 : sigaction() ( 계속 ) 이전의처리동작으로복원하기 #include <signal.h> static struct sigaction act, oact; /* SIGTERM 을위한과거의처리동작을남겨둔다. */ sigaction(sigterm, NULL, &oact); /* SIGTERM 을위한새로운처리동작을지정한다. */ act.sa_handler= SIG_IGN; sigaction(sigterm, &act, NULL); /* 여기서무언가작업을수행한다... */ /* 이제과거의행동을복원한다. */ sigaction(sigterm, &oact, NULL); Unix System Programming 30
Signal 관련시스템콜 (12) 시그널처리함수설정 : sigaction() ( 계속 ) 우아한퇴장 (A Graceful Exit) 프로그램수행중에임시로만든파일을삭제하고프로그램종료 /* 프로그램으로부터우아하게퇴장 (exit) 한다. */ #include <stdio.h> #include <stdlib.h> void g_exit(ints) { unlink ("tempfile"); fprintf(stderr, "Interrupted --exiting\n"); exit (1); } /* 특정시그널과연관 */ extern void g_exit(int);.. static struct sigaction act; act.sa_handler= g_exit; sigaction(sigint, &act, NULL); Unix System Programming 31
Signal 관련시스템콜 (13) 시그널 & 시스템호출 시스템호출수행도중에시그널이도착하는경우 대부분의경우, 시스템호출이종료될때까지아무런영향을미치지않는다 특수한경우, 시스템호출이인터럽트된다 느린장치에대한 read, write, open 등 -1을 return, errno에 EINTR을저장 if( write(tfd, buf, size) < 0) { if( errno== EINTR ) { warn("write interrupted");... } } Unix System Programming 32
Signal 관련시스템콜 (14) 시그널봉쇄 (blocking) : sigprocmask() #include <signal.h> int sigprocmask(int how, const sigset_t *set, sigset_t *oset) /* int how: 특정동작을지정 o SIG_SETMASK : 두번째인자시그널집합에서지정한시그널을봉쇄 o SIG_UNBLOCK : 시그널봉쇄를제거 o SIG_BLOCK : 현재봉쇄된시그널집합에두번째인자에서지정한시그널을추가 */ /* sigset_t *set : 처리를원하는시그널집합 */ /* sigset_t *oset : 원하는동작을수행하기이전의시그널집합 */ 프로세스가특정한동작을수행완료할때까지시그널처리를봉쇄한다 Unix System Programming 33
Signal 관련시스템콜 (15) 시그널봉쇄 (blocking) : sigprocmask() ( 계속 ) 예제 : sigset_t set1; /* 시그널집합을완전히채운다. */ sigfillset(&set1); /* 봉쇄 (block) 를설정한다. */ sigprocmask(sig_setmask, &set1, NULL); /* 극도로중요한코드를수행한다... */ /* 시그널봉쇄를제거한다 */ sigprocmask(sig_unblock, &set1, NULL); Unix System Programming 34
Signal 관련시스템콜 (16) 시그널봉쇄 (blocking) : sigprocmask() ( 계속 ) 예제 : /* signal blocking -- sigprocmask 의사용예를보인다. */ #include <signal.h> int main(void) { sigset_tset1, set2; /* 시그널집합을완전히채운다. */ sigfillset(&set1); /* SIGINT 와 SIGQUIT 를포함하지않는시그널집합을생성한다. */ sigfillset(&set2); sigdelset(&set2, SIGINT); sigdelset(&set2, SIGQUIT); /* 중요하지않은코드를수행... */ Unix System Programming 35
Signal 관련시스템콜 (17) /* 봉쇄를설정한다. */ sigprocmask(sig_setmask, &set1, NULL); /* 극도로중대한코드를수행한다... */ /* 하나의봉쇄를제거한다. */ sigprocmask(sig_unblock, &set2, NULL); /* (SIGINT 와 SIGQUIT 만을봉쇄 )*/ /* 덜중대한코드를수행한다... */ } /* 모든시그널봉쇄를제거한다. */ sigprocmask(sig_unblock, &set1, NULL); Unix System Programming 36
Signal 관련시스템콜 (18) 시그널송신 : kill() #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig) /* pid_t pid: 시그널을수신할프로세스 ID */ /* int sig : 전송할시그널번호 */ 지정된프로세스에게시그널을전송한다 첫번째인자 pid 값에따른동작차이 : 0 : 같은프로세스그룹에속하는모든프로세스에게시그널전송 -1 (euid가 root가아닐때 ): 보내는프로세스의 euid와같은 real uid를갖는모든프로세스에게시그널전송 -1 (euid가 root일때 ): 특수한시스템프로세스를제외한모든프로세스에게전송 <0 (not 1): pgid가 pid의절대값과같은모든프로세스에게전송 Unix System Programming 37
Signal 관련시스템콜 (19) 시그널송신 : kill() ( 계속 ) 예제 /* synchro -- kill 의예 */ #include <unistd.h> #include <signal.h> int ntimes= 0; int main(void) { pid_t pid, ppid; void p_action(int), c_action(int); static struct sigaction pact, cact; /* 부모를위해 SIGUSR1 행동을지정한다. */ pact.sa_handler= p_action; sigaction(sigusr1, &pact, NULL); switch (pid= fork()){ case 1:/* 오류 */ perror("synchro"); exit (1); Unix System Programming 38
Signal 관련시스템콜 (20) case 0:/* 자식 */ /* 자식을위해행동을지정 */ cact.sa_handler= c_action; sigaction(sigusr1, &cact, NULL); /* 부모의프로세스식별번호를얻음. */ ppid= getppid(); for (;;){ sleep (1); kill (ppid, GUSR1); pause(); } /* 결코퇴장 (exit) 않음. */ default: /* 부모 */ for(;;){ pause(); sleep (1); kill (pid, GUSR1); } /* 결코퇴장 (exit) 않음 */ } /* switch */ } /* main */ Unix System Programming 39
Signal 관련시스템콜 (21) void p_action (intsig) { printf("parent caught signal #%d\n", ++ntimes); } void c_action (intsig) { printf("child caught signal #%d\n", ++ntimes); } Unix System Programming 40
Signal 관련시스템콜 (22) 시그널송신 : kill() ( 계속 ) 예제프로그램 : 교재 pp.332~333, sendsigint.c Unix System Programming 41
Signal 관련시스템콜 (23) 시그널송신 : killpg() #include <sys/types.h> #include <signal.h> int killpg(int pgrp, int sig) /* int pgrp: 시그널을수신할프로세스그룹 ID */ /* int sig : 전송할시그널번호 */ 지정된프로세스그룹에게시그널을전송한다 시그널을전송하는프로세스와시그널을수신하는프로세스그룹의유효사용자 ID 가동일하여야한다 Unix System Programming 42
Signal 관련시스템콜 (24) 자신에게시그널송신 : raise() #include <signal.h> int raise(int sig) /* int sig : 전송할시그널번호 */ 자기자신에게지정된시그널을전송한다 Unix System Programming 43
Signal 관련시스템콜 (25) 타이머알람설정 : alarm() #include <unistd.h> unsigned int alarm(unsigned int seconds) /* unsigned int seconds : SIGALRM 시그널을보낼때까지의시간 ( 초단위 ) */ /* 호출한프로세스의알람클럭이남아있는시간을반환한다 */ 인자에지정한시간이경과한후에 SIGALRM 시그널을보내도록호출프로세스의알람클럭을설정한다 Unix System Programming 44
Signal 관련시스템콜 (26) 타이머알람설정 : alarm() ( 계속 ) #include <stdio.h> #include <signal.h> #define TIMEOUT 5 /* 초단위 */ #define MAXTRIES 5 #define LINESIZE 100 #define CTRL_G '\007' /* ASCII 벨 */ #define TRUE 1 #define FALSE 0 /* 타임아웃이발생했는지알아보기위해사용한다. */ static int timed_out; /* 입력줄을보관한다. */ static char answer[linesize]; char *quickreply(char *prompt) { void catch (int); int ntries; static struct sigaction act, oact; Unix System Programming 45
Signal 관련시스템콜 (27) /* SIGALRM 을포착하고, 과거행동을저장한다. */ act.sa_handler= catch; sigaction(sigalrm, &act, &oact); for (ntries=0; ntries<maxtries; ntries++){ timed_out = FALSE; printf("\n%s > ", prompt); /* 얼람시계를설정 */ alarm (TIMEOUT); /* 입력줄을가져온다. */ gets (answer); /* 얼람을끈다. */ alarm (0); /* timed_out이참이면, 응답이없는경우이다. */ if (!timed_out) break; } /* for */ Unix System Programming 46
Signal 관련시스템콜 (28) /* 과거행동을복원한다. */ sigaction(sigalrm, &oact, NULL); } /* 적절한값을복귀한다. */ return (ntries== MAXTRIES? ((char *)0) : answer); /* SIGALRM 을받으면수행한다. */ void catch (intsig) { /* 타임아웃플래그를설정한다. */ timed_out = TRUE; } /* 벨을울린다. */ putchar(ctrl_g); Unix System Programming 47
Signal 관련시스템콜 (29) 시그널수신까지프로세스중단 : pause() #include <unistd.h> int pause(void) /* 시그널에의해호출프로세스가종료하는경우에는반환되지않으며, 시그널을수신하여시그널처리함수를수행하고반환되었을때에반환된다 */ Unix System Programming 48
Signal 관련시스템콜 (30) 시그널수신까지프로세스중단 : pause() /* tml -- tell-me-later 프로그램 */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <signal.h> #include <unistd.h> #define TRUE 1 #define FALSE 0 #define BELLS "\007\007\007" /*ASCII bells */ int alarm_flag = FALSE; /* SIGALRM을처리할루틴 */ void setflag(intsig) { alarm_flag = TRUE; } main (intargc, char **argv) { Unix System Programming 49
Signal 관련시스템콜 (31) int main(int argc, char **argv) { int nsecs, j; pid_t pid; static struct sigaction act; if ( argc<=2 ){ fprintf(stderr, "Usage: tml#minutes message\n"); exit (1); } if ((nsecs=atoi(argv[1])*60) <= 0){ fprintf(stderr, " tml: invalid time\n"); exit (2); } /* 백그라운드프로세스를생성하기위해 fork한다. */ switch (pid= fork()){ case -1: /* 오류 */ perror("tml"); exit (1); case 0: /* 자식 */ break; default: /* 부모 */ printf("tmlprocess-id %d\n", pid); exit (0); } /* switch */ Unix System Programming 50
Signal 관련시스템콜 (32) /* 얼람을위한행동을지정한다. */ act.sa_handler= setflag; sigaction(sigalrm, &act, NULL); /* 얼람시계를켠다. */ alarm (nsecs); /* 시그널이올때까지중단 (pause)... */ pause(); /* 만일시그널이 SIGALRM 이면메시지를프린트하라. */ if (alarm_flag == TRUE){ printf(bells); for (j = 2; j < argc; j++) printf("%s", argv[j]); printf("\n"); } } exit (0); Unix System Programming 51
Signal 구현및동작 (1) 시그널처리를위한커널기능 시그널보내기 (kill) 시그널발견 : 커널수준수행에서사용자수준수행으로전이할때 사용자수준시그널처리함수등록 (signal) 사용자수준시그널처리함수호출 Unix System Programming 52
Signal 구현및동작 (2) 시그널처리를위한태스크자료구조 Unix System Programming 53
Signal 구현및동작 (3) 사용자수준시그널처리함수등록 Unix System Programming 54
시그널전송 Signal 구현및동작 (4) Unix System Programming 55
시그널발견 Signal 구현및동작 (5) Unix System Programming 56
시그널처리 Signal 구현및동작 (6) Unix System Programming 57