728x90
시그널
- 특정 상황이 되었을 때 운영체제가 프로세스에게 해당 상황이 발생했음을 알리는 일종의 메시지
시그널 등록
- 프로세스가 운영체제에서 발생하는 시그널을 받기 위해서는 해당 시그널을 등록해줘야 함
- signal 함수 : 등록해주는 함수
-> 시그널 상수값을 전달하고 그 시그널이 발생되었을 때 호출할 함수 포인터를 등록
#include <signal.h>
void (*signal(int signo, void (*func)(int)))(int);
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void timeout(int sig)
{
if(sig==SIGALRM) {
puts("Time out!");
}
alarm(2);
}
void keycontrol(int sig)
{
if(sig==SIGINT) {
puts("CTRL+C pressed");
}
}
int main(int argc, char *argv[])
{
int i;
signal(SIGALRM, timeout);
signal(SIGINT, keycontrol);
alarm(2);
for(i=0; i<3; i++)
{
puts("wait...");
sleep(100);
}
return 0;
}
- signal이 발생되면 프로세스에게 알려주기 위해 깨우기 때문에 sleep가 바로 빠져나옴
- sigaction : signal 함수는 운영체제에 따라 달리 동작할 수 있기 때문에 그에 따른 표준화가 되어있는 sigaction 함수를 사용하는 것이 나음
-> signo : 시그널 전달
-> act : 시그널 발생 시 호출된 함수에 대한 정보를 담고 있는 구조체 전달
-> old : 이전에 등록된 함수에 대한 정보를 얻음
#include <signal.h>
int sigaction(int signo, const struct sigaction* act, struct sigaction* oldact);
struct sigaction {
void (sa_handler)(int); // 호출되는 함수
sigset_t sa_mask;
int sa_flags;
}
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void timeout(int sig)
{
if(sig==SIGALRM)
puts("Time out!");
alarm(2);
}
int main(int argc, char *argv[])
{
int i;
struct sigaction act;
act.sa_handler=timeout; // 호출될 함수 등록
sigemptyset(&act.sa_mask); // sa_mask를 0으로 초기
act.sa_flags=0;
sigaction(SIGALRM, &act, 0);
alarm(2);
for(i=0; i<3; i++)
{
puts("wait...");
sleep(100);
}
return 0;
}
시그널 핸들링을 통한 좀비 프로세스의 소멸
- 자식 프로세스가 종료될 때의 시그널인 SIGCHLD을 등록해서 발생될 때 waitpid 함수를 호출하는 함수를 등록
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
void read_childproc(int sig)
{
int status;
pid_t id=waitpid(-1, &status, WNOHANG);
if(WIFEXITED(status))
{
printf("Removed proc id: %d \n", id);
printf("Child send: %d \n", WEXITSTATUS(status));
}
}
int main(int argc, char *argv[])
{
pid_t pid;
struct sigaction act;
act.sa_handler=read_childproc;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
sigaction(SIGCHLD, &act, 0);
pid=fork();
if(pid==0)
{
puts("Hi! I'm child process");
sleep(10);
return 12;
}
else
{
int i;
printf("Child proc id: %d \n", pid);
for(i=0; i<5; i++)
{
puts("wait...");
sleep(5);
}
}
return 0;
}
728x90
'Programming > Network' 카테고리의 다른 글
열혈 TCP/IP 10-5. TCP의 입출력 루틴(Routine) 분할 (0) | 2021.03.01 |
---|---|
열혈 TCP/IP 10-4. 멀티태스킹 기반의 다중접속 서버 (0) | 2021.03.01 |
열혈 TCP/IP 10-2. 프로세스 & 좀비(Zombie) 프로세스 (0) | 2021.03.01 |
열혈 TCP/IP 10-1. 프로세스의 이해와 활용 (0) | 2021.03.01 |
열혈 TCP/IP 09-3. TCP_NODELAY (2) | 2021.02.24 |