Unix Signal을 이용해 Client와 Server 사이에 Communication 프로그램
시그널 (SIGNAL)
유닉스 계열 운영체제에서 쓰이는 Software interrupt
process에 특정 이벤트가 발생했을 때 신호를 비동기적으로 보내는 것
- Signal을 받은 프로세스는 Signal에 따른 미리 지정된 기본 동작(default action)을 수행할 수 있고, 사용자가 미리 지정해 놓은 함수에 의해 무시하거나 특별한 처리를 할 수 있다.
ex)
리눅스에서 [Ctrl + c] || [Ctrl + z]를 누르면, 프로그램이 강제종료된다.
-> 프로그램이 실행중에 개입해 강제로 종료시킨 것
즉, 예외상황이 발생했을 때 신호가 가고, 운영체제에서 이를 캐치하여 해결을 위한 행동을 취한 것
시그널 종류
kill -l
SIGUSR1, SIGUSR2
- user define signal 1, 2
Signal 관련 함수
- (2) : System call
- (3) : Library function
signal
void (*signal(int signum, void (*handler)(int)))(int)
// signum : 시그널 번호
// *handler : 시그널을 처리할 핸들러
시그널 처리 방식을 설정
- SIG_DFL : 시그널 발생시 기존 방법으로 처리
- SIG_IGN : 무시
- FUNCTION_NAME : 프로그램에서 직접 처리
헤더 : <signal.h>
sigemptyset
int sigemptyset(sigset_t *set)
sigset_t 라는 집합에서 모든 시그널을 제거한다.
시그널을 하나씩 처리하거나, 여러개를 묶어서 한번에 처리할 수 있다.
헤더 : <signal.h>
return
- 성공 : 0
- 실패 : -1
sigaddset
int sigaddset(sigset_t *set, int signum)
sigset_t라는 집합에 signal을 추가하는 함수
return
- 성공 : 0
- 실패 : -1
sigaction (2)
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
// signum : 시그널 번호
// *act : 설정할 행동. 즉, signum에 대해 새롭게 지정할 처리 행동
// *oldact : 이전 행동. 이 함수를 호출하기 전 지정된 동작 조회
struct sigaction {
void (*sa_handler)(int);
// signum에 대한 동작을 나타내는 함수 포인터
void (*sa_sigaction)(int, siginfo_t *, void *);
// 시그널 핸들러를 실행하는 다른 방법
// siginfo_t : 받은 시그널에 대한 정보 제공
sigset_t sa_mask;
// sa_handler에 등록된 시그널 핸들러 함수가 실행되는 동안 차단할 신호의 집합
int sa_flags;
// 시그널 처리 프로세스의 행위를 수정하는 일련의 플래그 명시 (https://www.joinc.co.kr/w/man/2/sigaction)
// 핸들링 프로세스의 동작 변경을 허용.
// sa_sigaction 핸들러 사용을 위해선 여기에 SA_SIGINFO를 넣어야함
void (*sa_restorer)(void);
// 이 필드는 앱 사용 목적으로 만든게 아님. sigreturn과 관련된 필드
};
void handler(int signo, siginfo_t *siginfo, ucontext_t *context)
// signo : 시그널 핸들러를 호출할 시그널
// siginfo : 시그널이 발생한 원인을 담은 구조체 포인터
// context : 시그널이 전달될 때, 시그널을 받는 프로세스의 내부 상태를 담은 구조체 포인터
특정 시그널의 수신에 대해서 취할 액션을 설정하거나 변경하기 위해서 사용하는 함수
헤더 : <signal.h>
return
- 성공 : 0
- 실패 : -1
- sa_flags : 시그널 처리 프로세스의 행위를 수정하는 일련의 플래그 명시
- SA_SIGINFO : 시스템에 지정된 신호 동작을 사용하도록 한다.
- 해당 플래그는 handler가 하나가 아닌 3개의 인자를 취할 경우 sa_handler 대신 sa_sigaction의 siginfo_t를 이용할 수 있다.
siginfo_t {
int si_signo; /* 시그널 넘버 */
int si_errno; /* errno 값 */
int si_code; /* 시그널 코드 */
pid_t si_pid; /* 프로세스 ID 보내기 */
uid_t si_uid; /* 프로세스를 전송하는 실제 사용자 ID */
int si_status; /* Exit 값 또는 시그널 */
clock_t si_utime; /* 소모된 사용자 시간 */
clock_t si_stime; /* 소모된 시스템 시간 */
sigval_t si_value; /* 시그널 값 */
int si_int; /* POSIX.1b 시그널 */
void * si_ptr; /* POSIX.1b 시그널 */
void * si_addr; /* 실패를 초래한 메모리 위치 */
int si_band; /* 밴드 이벤트 */
int si_fd; /* 파일 기술자 */
}
kill (2)
int kill(pid_t pid, int sig)
// pid : 시그널 받을 프로세스의 id
// sig : pid로 지정된 프로세스에 보내려는 시그널
특정 프로세스 혹은 그룹 ID가 같은 모든 프로세스에게 시그널을 전송하는 함수
헤더 : <sys/types.h>, <signal.h>
pid
- 프로세스 식별자
- 양수 : 특정 프로세스 ID에만 시그널 전송
- 0 : 함수를 호출하는 프로세스와 같은 그룹에 있는 모든 프로세스에 시그널 전송
- -1 : 함수를 호출하는 프로세스가 전송할 수 있는 권한을 가진 모든 프로세스에 시그널 전송
- 음수 (-1 제외) : 첫 번째 인수 pid의 절대값 프로세스 그룹에 속하는 모든 프로세스에 시그널 전송
getpid
pid_t getpid(void)
실행중인 프로세스 ID를 구한다.
헤더 : <sys/types.h>, <unistd.h>
return : 항상 성공해 프로세스 ID 반환
pause
int pause(void)
시그널을 수신할 때까지 대기 상태를 유지하는 함수
헤더 : <unistd.h>
return : 항상 -1 반환
sleep
void sleep(int seconds)
seconds 초 만큼 대기하는 함수
헤더 : <unistd.h>
usleep
void usleep(unsigned long useconds)
지정한 마이크로 초 동안 대기상태가 되는 함수
헤더 : <unistd.h>
exit
void exit(int status)
// status 0 : 정상종료 EXIT_SUCCESS
// status 1 : 에러 메세지 종료 EXIT_FAILURE
프로세스를 종료하는 함수. 시스템 입장에서 return 문과 동일하다.
- exit() : 바로 프로세스 종료
- return : 뒤 문장 실행하며 종료
헤더 : <stdlib.h>
Unicode character
ASCII 문자는 모든 문자의 첫 번째 비트가 0
유니코드는 ASCII와 구분하기 위해 첫 번째 비트를 1로 설정
shell은 UTF-8을 지원하는데, 이를 읽는 소프트웨어가 1비트로 시작하는 바이트를 만나면 0비트를 만나기 전까지 1비트의 수를 계산
그 후 처음 만난 0비트를 제외한 비트는 다음 바이트로 넘어간다.
참고 자료
- https://raidho.tistory.com/72
- https://bingu.tistory.com/5?category=902575
- https://ko.wikipedia.org/wiki/%EC%9C%A0%EB%8B%89%EC%8A%A4_%EC%8B%A0%ED%98%B8
- https://jhnyang.tistory.com/143
- https://blockdmask.tistory.com/23
- https://velog.io/@t1won/Unix-signal
- https://reakwon.tistory.com/215
- https://velog.io/@bahn/Minitalk
'42SEOUL' 카테고리의 다른 글
[push_swap] (0) | 2022.07.03 |
---|---|
[born2beroot] 서브젝트 설정 (0) | 2022.06.17 |
[born2beroot] Virtual Box 세팅하기 (0) | 2022.06.04 |
[born2beroot] 개념 정리 (0) | 2022.05.22 |
[ft_printf] printf() (0) | 2022.04.22 |