U E D R , A S I H C RSS

Linux Programming/Signal Handling


1. signal ?

위키 페디아의 정의를 빌리자면 시그널은 한 프로세서와 기타 다른 프로세스 사이에 전송되는 비동기적 이벤트 라고 한다.

유닉스 시스템에서 어떤 이벤트(event)가 발생하면 이것을 프로세스 사이에 알리는 수단으로 시그널이 사용된다.
쉽게 MFC비유하여 설명하는 시그널은 메시지와 비슷하다고 보면 된다. 실제로 signal 함수를 이용해서 우리는 MFC에서 이벤트와 이벤트 핸들러를 연결하듯 프로그래밍을 한다는 사실을 알 수 있다. (이렇게 보면 정말로 유닉스가 C로 짜여있다는 것을 확실하게 알 수 있다.)

2. 대표적 signal

SIGABRT - process aborted
SIGALRM - signal raised by alarm
SIGBUS - bus error "access to undefined portion of memory object"(SUS)
SIGCHLD - child process terminated, stopped (*or continued)
SIGCONT - continue if stopped
SIGFPE - floating point exception -- "erroneous arithmetic operation"(SUS)
SIGHUP - hangup
SIGILL - illegal instruction
SIGINT - interrupt
SIGKILL - kill
SIGPIPE - write to pipe with no one reading
SIGQUIT - quit
SIGSEGV - segmentation violation
SIGSTOP - stop executing
SIGTERM - termination
SIGTSTP - terminal stop signal
SIGTTIN - background process attempting to read ("in")
SIGTTOU - background process attempting to write ("out")
SIGUSR1 - user defined 1
SIGUSR2 - user defined 2
SIGURG - urgent data available on socket

SIGPOLL - pollable event
SIGPROF - profiling timer expired
SIGSYS - bad syscall
SIGTRAP - trace/breakpoint trap
SIGVTALRM - signal raised by timer counting virtual time -- "virtual timer expired"(SUS)
SIGXCPU - CPU time limit exceeded
SIGXFSZ - file size limit exceeded

3. sample code

int signal() 예제
~cpp
/**
code written by eternalbleu@gmail.com
desc: ctrl + c handling
**/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig);

int main(int argc, char **argv)
{
	int state;
	int num = 0;

	signal(SIGINT, handler);

	while(1)
	{
		printf("%d : waiting \n", num ++);
		sleep(2);
		if(num > 5)
		break;
	}
	return 0;
}

void handler(int sig)
{
//	signal(SIGINT, handler);
	printf("which signal is passed : %d \n", sig);
}

int sigaction() 예제
~cpp
/**
code written by eternalbleu@gmail.com
desc: ctrl + c handling
**/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void handler(int sig);

int main(int argc, char **argv)
{
	int state;
	int num = 0;

	struct sigaction act;
	act.sa_handler	=	handler;
	sigemptyset(&act.sa_mask);
	act.sa_flags	=	0;

	state	=	sigaction(SIGINT, &act, 0);

	if (state != 0)
	{
		puts("sigaction() error");
		exit(1);
	}
		
	while(1)
	{
		printf("%d : waiting \n", num ++);
		sleep(2);
		if(num > 5)
		break;
	}
	return 0;
}

void handler(int sig)
{
	printf("which signal is passed : %d \n", sig);
}
당연히 이해를 위해서는 함수 포인터를 알아야하며, 그 이외에는 굉장히 단순하다는 것을 알 수 있다.
이미 OS 에서 모든 처리를 다해주기 때문에 프로그래머는 핸들러만 정의하면 만사 OK다

4. signal 을 이용한 타이머

~cpp
/**
code written by eternalbleu@gmail.com
desc: timer program that use SIGALRM signal.
**/
#include <stdio.h>
#include <unistd.h>
#include <signal.h>

void timer(int sig);

int main(int argc, char **argv)
{
	int state;
	int num = 0;

	struct sigaction act;
	act.sa_handler	=	timer;
	sigemptyset(&act.sa_mask);
	act.sa_flags	=	0;
	
	state	=	sigaction(SIGALRM, &act, 0);
	
	if (state != 0) {
		puts("sigaction() error");
		exit(1);
	}

	alarm(5);

	while(1) {
		puts("waiting");
		sleep(2);
	}
	return 0;
}

void timer(int sig)
{
	puts("this is time for you to reserve");
	exit(0);
}
----
LinuxProgramming
Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:38
Processing time 0.0126 sec