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

+ Recent posts