Search
Duplicate

minitalk

Holy Graph
2Circle
간략한 내용
시그널 공부하기
적정 기간
1 week
제작에 참여한 사람
진행 중인 사람
최종 편집일
Oct 12
통과한 사람
1 more property
빠르게 끝내고 넘어가자

0. Minitalk subject!

Mandatory Part

서로 의사 소통 가능한 client, server 프로그램을 만든다.
server가 먼저 켜지고, 실행되면 PID 를 먼저 출력해야한다.
클라이언트가 받아야하는 파라미터
서버 PID
전송할 문자열
클라이언트는 서버한테 넘겨받은 문자열을 보내준다. 서버가 문자열을 받으면 서버는 표시해야한다.
통신은 UNIX 시그널을 통해서만 이뤄져야한다.
서버는 꽤 빠르게 문자열을 출력해야한다...? 1초에 100개 문자열은 엄청 느린것이다...?
서버는 여러개의 클라이언트한테 한번에 문자열을 받을 수 있어야한다.
시그널 SIGUSR1 과 SIGUSR2 만 써야한다.

Bonus

reception acknowledgment system
유니코드 지원

1. 개념

시그널이란?

시그널 집합이란?

그냥 시그널을 한번에 여러개를 표현하기 위한 sigset_t 구조체 참고
비트 마스크를 활용한다.
실제 구조체는 아래와같이 생겼다.
typedef struct { unsigned int __sigbits[4]; } sigset_t;
C
복사
sigaction 구조체에서 쓰인다.

2. 함수 정리하기

이미 아는 함수

write, malloc, free, exit

getpid

function

#include <unistd.h> pid_t getpid(void)
C
복사

return value

프로세스의 ID 를 반환 합니다.

example

#include <stdio.h> #include <unistd.h> int main() { printf("PID = %d\n", getpid()); return 0; }
C
복사

sigemptyset

시그널 집합 비우기

function

#include <signal.h> int sigemptyset(sigset_t *set);
C
복사

patameters

비워질 sigset_t 구조체

return value

성공하면 0
실패하면 -1

example

#include <signal.h> int main() { sigset_t set; sigemptyset(&set); }
C
복사

sigaddset

function

#include <signal.h> int sigaddset(sigset_t *set, int signo);
C
복사

patameters

추가될 sigset_t 구조체
추가할 시그널

return value

성공하면 0
실패하면 -1

example

#include <signal.h> int main() { sigset_t set; sigemptyset(&set); sigaddset(&set, SIGINT); }
C
복사

sigaction

signal 함수의 업그레이드 된 버전 참고

function

#include <signal.h> int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
C
복사

patameters

signum : 시그널 번호
act : NULL또는 처리할 방법을 담은 sigaction 구조체의 주소
oldact : NULL또는 기존에 시그널을 처리하던 방법을 저장할 sigaction 구조체의 주소
sigaction 구조체
struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }
C
복사
sa_handler : 시그널 발생했을떄 처리할 함수
sa_mask : sa_handler 에 등록된 시그널 핸들러 함수가 실행되는 동안 블럭 되어야하는 시그널의 마스크
sa_flag : 처리 프로세스 플래그

return value

성고하면 0
실패하면 1

example

#include <signal.h> #include <unistd.h> #include <string.h> #include <stdio.h> void sig_int(int signo); void sig_usr(int signo); int main() { int i = 0; struct sigaction intsig, usrsig; usrsig.sa_handler = sig_usr; sigemptyset(&usrsig.sa_mask); usrsig.sa_flags = 0; intsig.sa_handler = sig_int; sigemptyset(&intsig.sa_mask); intsig.sa_flags = 0; // SIGINT에 대해서 sig_int를 등록한다. if (sigaction(SIGINT, &intsig, 0) == -1) { printf ("signal(SIGINT) error"); return -1; } // SIGUSR2에 대해서 usrsig를 등록한다. if (sigaction(SIGUSR2, &usrsig, 0) == -1) { printf ("signal(SIGUSR2) error"); return -1; } while(1) { printf("%d\n", i); i++; sleep(1); } } void sig_int(int signo) { printf("sig_int\n"); } void sig_usr(int signo) { printf("sig_usr2\n"); }
C
복사

pause

함수가 호출되면 시그널을 수신할 떄까지 대기 상태로 빠진다. 참고

funciton

#include <unistd.h> int pause(void)
C
복사

return value

무조건 -1

example

#include <unistd.h> #include <stdio.h> int main(void) { printf("시그널 기다리는중!\n"); pause(); printf("시그널 받았다!"); }
C
복사

sleep

함수가 호출되면 지정된 초만큼 대기상태로 빠진다.

funciton

#include <unistd.h> unsigned int sleep(unsigned int seconds);
C
복사

return value

정상 종료 : 0
시그널 받아서 중간에 멈추면 : 남은 시간

example

#include <unistd.h> #include <stdio.h> int main(void) { printf("시작\n"); sleep(3); printf("3초 지났다!"); }
C
복사

usleep

함수가 호출되면 지정된 마이크로 초만큼 대기상태로 빠진다.

funciton

#include <unistd.h> int usleep(useconds_t usec)
C
복사

parameters

The type useconds_t is an unsigned integer type capable of holding integers in the range [0,1000000].
0 ~ 1000000 사이의 값

return value

성공 : 0
실패 : -1

example

#include <unistd.h> #include <stdio.h> int main(void) { printf("시작\n"); sleep(1000 * 1000); printf("1초 지났다!"); }
C
복사

3. 구현

프로세스 사이에서 signal 을 주고 받는것에 대해서 이해가 되었을 것이다.
그럼 이제 client 에서 server 로 문자열을 보내보자
근데 어떻게 문자열을 시그널을 통해서 보낼 수 있을까?
정답 : bit 단위로 잘라서 순차적으로 보낸다!
이때, SIGUSR1 로 시그널을 보내면 1, SIGUSR2 로 시그널을 보내면 0 으로 인식한다.
예시
A 라는 문자 하나를 보낸다고 생각해보자
A 를 bit 로 표현하면 01000001 이다.
client
100 마이크로 초 마다 server 로 시그널을 보낼건데,
A 의 첫번째 bit 가 1 이므로 SIGUSR1 을 보내고
A 의 두번째 bit 가 0 이므로 SIGUSR0 을 보내고
A 의 세번째 bit 가 0 이므로 SIGUSR0 을 보내고
...
A 의 여덟번째 bit 가 0 이므로 SIGUSR0 을 보낸다.
server
시그널을 받을때마다
SIGUSR1 이면 bit의 오른쪽 끝에 1을 추가하고
SIGUSR0 이면 bit 의 오른쪽 끝에 0을 추가한다.
최종적으로 문자 A 가 완성된다.
문자 A 를 출력한다.

4. 평가표

서버가 pid 를 띄우는지
./client PID STRING 했을때 전송이 잘 되는지
time 써서 시간 잴떄 문자열 10, 100 는 1초 미만, 1000개는 2초 미만으로
SIGUSR1 이랑 SIGUSR2 를 썼는지
8bit 씩 잘라서 보냈는지
전역변수를 1개 이하로 썼는지

5. 참고