kyo
Hyo's Inside
kyo
전체 방문자
오늘
어제
  • 분류 전체보기 (29)
    • Computer Science (1)
    • 42Seoul (6)
    • Algorithm (9)
      • Theory (5)
      • Daily PS (4)
    • Language & Framework (12)
      • Spring (0)
      • Java (11)
      • React (0)
      • C&C++ (0)
      • Node.js (1)
    • Dev (1)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • LEMP
  • 42SEOUL
  • 알고리즘
  • 백준
  • minitalk
  • mutex
  • Algorithm
  • 도커
  • sigaction
  • 슬랙
  • Greedy
  • 참고자료 : 이것이 코딩테스트이다 with 파이썬
  • slack
  • 세미나
  • docker
  • Nginx
  • 슬랙봇
  • philosophers
  • 빅오
  • 자바

최근 글

티스토리

kyo

Hyo's Inside

[42 Seoul] Minitalk : signal 함수로 IPC(Inter-Process Communication) 구현
42Seoul

[42 Seoul] Minitalk : signal 함수로 IPC(Inter-Process Communication) 구현

2021. 7. 2. 12:21

1. signal 이란

 

시그널(signal)은 software interrupt 로 프로세스 간의 비동기적 이벤트와 데이터를 공유, 전송할 수 있도록 운영체제에서 제공되는 IPC 중 하나이다.

signal을 프로세스에 보내면 각 signal에 지정된 동작을 수행한다. 

 

2. signal 함수

  • signal 

signal 함수는 <signal.h> 에 정의되어 있으며 시그널을 받아 지정된 함수를 실행할 수 있다. 

signal(SIGINT, (void *)sig_handler);

 

아래는 signal의 종류이다.

 

SIGHUP 터미널 연결이 끊어졌을 때 이 터미널과 연결된 세션 리더 또는 세션에 속한 모든 프로세스들에게 보내지는데 이 시그널을 받으면 종료
SIGINT 터미널에서 인터럽트 키를 눌렀을 때 보내지는데 이 시그널 받으면 종료
SIGILL 불법 명령어를 실행할 때 보내지는데 이 시그널을 받으면 코어 덤프 후 종료
SIGABRT Abort 함수를 호출하면 보내는데 이 시그널을 받으면 코어 덤프 후 종료
SIGBUS 하드웨어 결함이 탐지 되면 보내는데 이 시그널 받으면 종료
SIGFPE 0으로 나누기, 부동소수점 오류 등이 발생했을 때 보내지는데 이 시그널을 받으면 코어 덤프 후 종료
SIGKILL 프로세스를 종료시키기 위해 보내는데 이 시그널 받으면 반드시 종료
SIGUSR1 사용자가 정의해 사용할 수 있는 시그널로 이 시그널을 받으면 종료
SIGSEGV 잘못된 메모리 주소를 접근하고자 할 때 보내지는데 이 시그널 받으면 코어 덤프 후 종료
SIGUSR2 사용자가 정의해 사용할 수 있는 시그널로 이 시그널을 받으면 종료
SIGPIPE 닫힌 파이프에 쓰고자 할 때 보내지는데 이 시그널을 받으면 코어 덤프 후 종료
SIGALRM Alarm 함수를 호출하면 보내는데 이 시그널을 받으면 종료
SIGTERM 프로세스를 종료시키기 전에 하던 일을 정리하고 종료 할 것을 알릴 때 보냄
SIGCHLD 자식 프로세스가 종료되면 부모 프로세스에 보내짐, wait에서 이 시그널이 의해 깨어남, 이 시그널 받으면 무시
SIGCONT 중단되어 있는 프로세스가 이 시그널을 받으면 실행, 실행 중인 프로세스가 받으면 무시
SIGSTOP 프로세스를 멈추기 위해 보내는데 이 시그널을 받으면 반드시 멈춤
SIGTSTP 터미널에서 일시 중지 키를 눌렀을 때 보내지는데 이 시그널을 받으면 멈춤
SIGTTIN 백그라운드 작업 중인 프로세스가 표준 입력을 하려할 때 현재 실행 중인 프로세스에 보내는데 이 시그널을 받으면 멈춤
SIGTTOU 백그라운드 작업 중인 프로세스가 표준 출력을 하려할 때 현재 실행 중인 프로세스에 보내는데 이 시그널을 받으면 멈춤
SIGSYS
잘못된
 시스템 호출을 했을 때 보내지는데 이 시그널을 받으면 코어 덤프 후 종료

 

  • sigaction

sigaction 함수는 signal 보다 다양한 기능을 제공하는 함수이다. 

int	sigaction(int, const struct sigaction * __restrict,
	    struct sigaction * __restrict);

sigaction구조체로 가져올 데이터와 핸들링 함수를 지정할 수 있다.

sigaction 구조체는 <sys/signal.h>에 선언되어 있으며 signal 마스크와 flags를 설정할 수 있다.

struct sigaction {
        void     (*sa_handler)(int);
        void     (*sa_sigaction)(int, siginfo_t *, void *);
        sigset_t   sa_mask;
        int        sa_flags;
        void     (*sa_restorer)(void);
};

sa_handler - signal을 받아 실행시킬 함수에 대한 포인터이다.

sa_sigaction - 시그널 핸들러를 실행하는 다른 방법이다. 추가 매개변수를 받아 siginfo_t* 구조체를 통해 많은 정보를 받아올 수 있다.

sa_mask - 핸들러 실행 중에 블로킹 될 시그널을 설정할 수 있다.

sa_flags -  SA_SIGINFO flag 를 사용하면 sa_sigaction을 사용해야하며 아래와 같은 정보를 받아올 수 있다.

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

kill 함수는 시그널을 보낼 수 있는 함수이다.

아래와 같이 선언된다.

int kill(pid_t pid, int sig);
// pid : 시그널을 받을 pid
// signal : 넘버
  • getpid

현재 실행중인 process의 pid를 가져오는 함수

  • pause

pause 함수를 사용하면 signal이 들어올때 까지 대기한다.

while(1){
	pause();
}

 


1. Mandatory Part

  • 여러분께서는 클라이언트와 서버가 서로 통신하는 프로그램을 작성하셔야 합니다.
  • 서버와 클라이언트 중 서버가 먼저 실행되어야 하며, 클라이언트가 런치가 될 때에 PID를 표시해야 합니다.
  • 클라이언트가 실행될 때 다음의 매개변수를 받습니다 :
    • 서버 PID
    • 전송할 문자열
  • 클라이언트는 매개변수로 전달한 문자열을 서버로 통신해야 합니다. 서버는 문자열이 수신되면 해당 문자열을 표시해야 합니다.
  • 여러분이 작성하신 서버와 클라이언트의 통신은 오직 UNIX signal을 이용하여야만 합니다.
  • 서버는 문자열을 매우 빠른 속도로 표시할 수 있어야 합니다. 즉, 표시되는 시간이 너무 길다고 생각된다면, 그건 너무 길다고 여겨야 합니다. (힌트 : 100개의 문자로 이루어진 문자열을 표시하는 데 1초가 걸린다면 그건 어마어마하게 긴 것입니다.)
  • 서버가 재시작할 필요없이 여러 클라이언트로부터 문자열을 연속으로 수신할 수 있어야 합니다.
  • SIGUSR1과 SIGUSR2 두 신호만 사용할 수 있습니다.

과제에서 요구하는 SIGUSR1,  SIGUSR2 두가지 신호만 사용하여 server에게 문자열을 전송하는 방식을 고민하다  char를 이진법으로 바꾼 후 bit로 0과 1로 구분하여 전송한 뒤 server에서 받아와 유니코드로 변환 후 char 하나씩 출력하는 방식으로 구현하였다.

 

비트를 순차적으로 받아올때 쉬프트 연산을 사용하여 비트를 더해가며 8개의 bit를 만들었으며 static 변수를 사용해 함수를 재호출할때에도 소멸되지 않고 유지될 수 있게 하였다.

서버를 실행시키면 pid를 출력, 계속해서 시그널 대기를 하고 클라이언트는 메세지를 보낼 pid와 문자열을 받아 전송한다.

 

'42Seoul' 카테고리의 다른 글

[42Seoul] Philosophers : 뮤텍스와 세마포어  (0) 2021.08.14
[42Seoul] Push_Swap : 정렬 알고리즘 구현  (0) 2021.06.16
[42Seoul] ft_server (Docker + LEMP)  (0) 2021.03.01
[42Seoul] ft_printf - 나의 printf 구현하기  (0) 2021.02.06
[42Seoul] Netwhat - 네트워크 및 시스템 관리  (0) 2021.01.23
    '42Seoul' 카테고리의 다른 글
    • [42Seoul] Philosophers : 뮤텍스와 세마포어
    • [42Seoul] Push_Swap : 정렬 알고리즘 구현
    • [42Seoul] ft_server (Docker + LEMP)
    • [42Seoul] ft_printf - 나의 printf 구현하기
    kyo
    kyo
    〈 🖥〉

    티스토리툴바