Minitalk

MELIES·2025년 2월 23일

Minitalk

SIGUSR1과 SIGUSR2 두 가지 시그널만을 사용하여 문자열을 전송하는 클라이언트-서버 구조 통신 프로그램

Mandantory

  • 서버는 실행 시 자신의 PID를 출력
  • 클라이언트는 서버 PID와 전송할 문자열을 인자로 받음
  • 오직 SIGUSR1, SIGUSR2 시그널만 사용 가능
  • 여러 클라이언트의 동시 접속 지원
  • 프로그램당 하나의 전역변수 사용 가능(클라이언트, 서버)
  • 메모리 누수 없어야 함

허용함수

write
◦ ft_printf (직접 구현한 경우)
signal
◦ sigemptyset
◦ sigaddset
◦ sigaction
kill
getpid
◦ malloc
◦ free
pause
◦ sleep
usleep
◦ exit

비트 단위 통신

void send_char(int pid, int c)
{
    int i;
    
    i = 8;
    while (i--)
    {
        if (c % 2)
            kill(pid, SIGUSR1);  // 1을 전송
        else
            kill(pid, SIGUSR2);  // 0을 전송
        c /= 2;
        usleep(50);
    }
}
  • 8비트 단위의 효율적인 문자 처리
  • 추가 버퍼 없이 직접 처리
  • 즉시 출력 방식으로 메모리 사용 최소화

시그널 핸들링

void print_sig(int signum)
{
    static char temp;
    static int  bit;

    if (signum == SIGUSR1)
        temp |= (1 << bit);
    bit++;
    if (bit == 8)
    {
        write(1, &temp, 1);
        bit = 0;
        temp = 0;
    }
}

메모리 및 시그널 처리 최적화

시그널 손실 방지

UNIX 시스템은 동일한 종류의 시그널이 이미 대기 중일 때 추가 시그널을 큐에 넣지 않음
이를 방지하기 위해 usleep()을 사용하여 시그널 간 적절한 간격을 둠

유효하지 않은 PID 값에 대한 검증을 수행

메모리 관리

void print_sig(int signum)
{
    static char temp;
    static int  bit;
    
    if (signum == SIGUSR1)
        temp |= (1 << bit);
    bit++;
    if (bit == 8)
    {
        write(1, &temp, 1);
        bit = 0;
        temp = 0;
    }
}
  • static 변수 2개로 상태 유지 (힙 메모리 할당이 필요 없음)
  • 메모리 할당을 하지 않아 메모리 누수나 dangling pointer 같은 위험이 없음
  • 프로그램 종료 시 자동으로 메모리가 해제

통신 효율성

  • 비트 전송 간격(usleep) 조절을 통한 전송 속도와 안정성의 균형
  • 효율적인 비트 연산을 통한 문자 재구성
  • 8비트(1바이트) 단위로 문자를 처리하면서 추가 버퍼가 필요 없음
    각 비트를 즉시 처리하고 문자가 완성되면 바로 출력하는 방식
  • 복잡한 버퍼나 큐 구조 없이 비트 연산만으로 구현

배운점 !

운영체제와 직접 상호작용하는 저수준 프로그래밍 경험
UNIX 시그널의 동작 방식
비동기 통신의 특성과 처리 방법
시스템 콜의 적절한 활용 방법

profile
42 Seoul

0개의 댓글