FIFO (Named Pipe) : 프로세스 간 통신의 기본

2026. 2. 22. 17:35·Dev/System Programming

들어가며

프로세스 간 통신(IPC)을 공부하다 보면 가장 먼저 만나는 개념이 Pipe입니다.
그런데 Pipe는 부모-자식 프로세스처럼 혈연관계가 있는 프로세스들끼리만 통신할 수 있다는 제약이 있죠.

 

만약 완전히 독립적인 두 프로그램이 통신하려면 어떻게 해야 할까요?
바로 여기서 FIFO(Named Pipe)가 등장합니다.

 

이 글에서 FIFO의 개념부터 실제 구현까지, 직접 코드를 작성하며 겪은 문제들과 해결 과정을 공유하겠습니다.


FIFO란?

FIFO = First In First Out

FIFO는 "First In First Out"의 약자로, 먼저 들어간 데이터가 먼저 나오는 자료구조입니다.

마치 은행 대기줄처럼 선착순으로 처리되죠.

 

입구 →  [A][B][C][D]  → 출구
        ↑           ↓
      나중에       먼저
      들어감       나감

 

Named Pipe = FIFO

Linux에서 FIFO는 "Named Pipe"라고도 불립니다.

왜냐하면 일반 Pipe와 달리 파일시스템에 이름을 가진 파일로 존재하기 때문입니다.

$ mkfifo /tmp/myfifo
$ ls -l /tmp/myfifo
prw-rw-r-- 1 user user 0 Feb 21 10:00 /tmp/myfifo
↑
p = pipe (FIFO)

 

파일 타입이 `p`로 표시되는 것을 볼 수 있습니다. 이것이 바로 FIFO 파일입니다.


Pipe vs FIFO

두 개념을 비교하면 차이가 명확해집니다.

특징 Pipe FIFO (Named Pipe)
이름 익명 (이름 없음) 파일명으로 접근
프로세스 관계 부모-자식 관계 필수 완전히 독립적
파일시스템 존재하지 않음 파일로 존재
생성 방법 pipe() mkfifo()
사용 예시 ls | grep 독립 프로그램 간 통신

 

Pipe의 제약

// Pipe는 fork() 필수
int pipefd[2];
pipe(pipefd);
fork();  // 부모-자식 관계!

if (pid == 0) {
    // 자식: read
} else {
    // 부모: write
}

 

FIFO의 자유로움

// 프로세스 A (writer.c)
int fd = open("/tmp/myfifo", O_WRONLY);
write(fd, "Hello", 5);

// 프로세스 B (reader.c) - 완전히 독립!
int fd = open("/tmp/myfifo", O_RDONLY);
read(fd, buf, 100);

실전: FIFO Chat 만들기

이론만으로는 부족하죠. 직접 간단한 채팅 프로그램을 만들어 봅시다.

 

1단계 : FIFO 생성

#include <sys/stat.h>

#define FIFO_PATH "/tmp/chat_fifo"

// FIFO 생성
if (mkfifo(FIFO_PATH, 0666) == -1) {
    perror("mkfifo");
    exit(1);
}

// 권한: 0666 = rw-rw-rw-

 

2단계 : Writer 프로그램

// fifo_writer.c
int main(void)
{
    char message[256];
    int fd;
    
    // FIFO 열기 (쓰기 모드)
    fd = open(FIFO_PATH, O_WRONLY);
    
    while (1) {
        printf("You: ");
        fgets(message, sizeof(message), stdin);
        
        if (strcmp(message, "quit\n") == 0)
            break;
        
        // 메시지 전송
        write(fd, message, strlen(message) + 1);
    }
    
    close(fd);
    return 0;
}

 

3단계 : Reader 프로그램

// fifo_reader.c
int main(void)
{
    char message[256];
    int fd;
    
    // FIFO 열기 (읽기 모드)
    fd = open(FIFO_PATH, O_RDONLY);
    
    while (1) {
        ssize_t n = read(fd, message, sizeof(message));
        
        if (n == 0) {  // EOF
            printf("Writer disconnected\n");
            break;
        }
        
        printf("Received: %s", message);
    }
    
    close(fd);
    unlink(FIFO_PATH);  // FIFO 삭제
    return 0;
}

 

실행 방법

# 터미널 1
$ gcc fifo_reader.c -o reader
$ ./reader
Opening FIFO...
(Waiting for writer...)

# 터미널 2
$ gcc fifo_writer.c -o writer
$ ./writer
Connected!
You: Hello!
You: How are you?
You: quit

길이 프로토콜

 

실무에서는 메시지 길이를 먼저 보내는 프로토콜을 많이 사용합니다.

// Writer
uint32_t msg_len = strlen(message) + 1;
write(fd, &msg_len, sizeof(msg_len));  // 길이 먼저
write(fd, message, msg_len);           // 메시지

// Reader
uint32_t msg_len;
read(fd, &msg_len, sizeof(msg_len));   // 길이 먼저
read(fd, message, msg_len);            // 정확히 msg_len만큼

 

이렇게 하면 메시지 경계를 정확히 알 수 있어서 훨씬 안정적입니다.


FIFO의 특성

Blocking I/O

FIFO의 기본 동작은 blocking입니다.

 

// Writer
fd = open("/tmp/myfifo", O_WRONLY);
// ↑ Reader가 열 때까지 블로킹!

// Reader
fd = open("/tmp/myfifo", O_RDONLY);
// ↑ Writer가 열 때까지 블로킹!

 

동작 순서:

T0: Reader: open() 호출 → 블로킹...
T1: Writer: open() 호출
T2: 둘 다 연결됨!
T3: Reader: open() 리턴
T4: Writer: open() 리턴

 

EOF 처리:

Writer가 FIFO를 닫으면 Reader는 EOF를 받습니다.

// Writer
write(fd, "Last message", 13);
close(fd);  // EOF 전달!

// Reader
while (1) {
    n = read(fd, buf, size);
    if (n == 0) {  // EOF
        printf("Writer disconnected\n");
        break;
    }
    process(buf);
}

실무 활용 사례

1. 로그 수집 시스템

Application → [FIFO] → Log Collector → File/DB

여러 애플리케이션이 하나의 FIFO에 로그를 쓰면
Log Collector가 중앙에서 수집/저장

 

2. 프로세스 간 명령 전달

Application → [FIFO] → Log Collector → File/DB

여러 애플리케이션이 하나의 FIFO에 로그를 쓰면
Log Collector가 중앙에서 수집/저장

 

3. 파이프라인 구축

$ mkfifo /tmp/data_pipe
$ producer > /tmp/data_pipe &
$ consumer < /tmp/data_pipe

주의 사항

1. FIFO는 단방향

양방향 통신이 필요하면 FIFO 2개를 만들어야 합니다.

mkfifo("/tmp/fifo_to_server", 0666);
mkfifo("/tmp/fifo_to_client", 0666);

// Client
write(fd_to_server, request, len);
read(fd_from_server, response, len);

 

2. 정리 필수

프로그램 종료 시 FIFO 파일을 삭제해야 합니다.

close(fd);
unlink(FIFO_PATH);

 

3. SIGPIPE 조심

Reader가 먼저 종료하면 Writer가 SIGPIPE 시그널을 받아 종료될 수 있습니다.

// 해결책: SIGPIPE 무시
signal(SIGPIPE, SIG_IGN);

// 또는 에러 처리
if (write(fd, data, len) == -1) {
    if (errno == EPIPE) {
        printf("Reader closed\n");
    }
}

성능 비교

FIFO vs Shared Memory 벤치마크 (1MB 데이터 전송):

FIFO:           5-10 ms
Shared Memory:  0.5-1 ms

→ FIFO는 SHM의 약 10배 느림

 

이유는 FIFO는 Kernel을 경유하기 때문입니다.

FIFO:
Process A → [User Space]
          ↓
        [Kernel Space]  (복사!)
          ↓
        [User Space] → Process B

Shared Memory:
Process A ↔ [Shared Memory] ↔ Process B
           (복사 없음!)

 

속도가 중요하다면 Shared Memory를, 간단한 통신이면 FIFO를 사용하는 게 좋습니다.


디버깅 팁

FIFO 상태 확인

# FIFO 파일 확인
$ ls -l /tmp/myfifo
prw-rw-r-- 1 user user 0 Feb 21 10:00 /tmp/myfifo

# FIFO 내용 확인 (주의: 블로킹!)
$ cat /tmp/myfifo  # Reader처럼 동작

# 다른 터미널에서
$ echo "test" > /tmp/myfifo  # Writer처럼 동작

 

strace로 시스템 콜 추적

$ strace -e trace=open,read,write ./reader

open("/tmp/chat_fifo", O_RDONLY)       = 3
read(3, "Hello\0", 256)                = 6
read(3, "World\0", 256)                = 6

마치며

FIFO는 가장 기본적인 IPC 메커니즘 중 하나지만, 실제로 구현해 보면 생각보다 고려할 게 많습니다.

 

배운 점:

  • Null terminator 처리의 중요성
  • 버퍼 초기화 필수
  • 길이 프로토콜로 견고하게
  • Blocking 특성 이해
  • EOF 처리

다음 공부는 Shared Memory를 공부해볼 예정입니다.


참고 자료

  • https://man7.org/linux/man-pages/man3/mkfifo.3.html
 

mkfifo(3) - Linux manual page

mkfifo(3) — Linux manual page mkfifo(3) Library Functions Manual mkfifo(3) NAME         top mkfifo, mkfifoat - make a FIFO special file (a named pipe) LIBRARY         top Standard C library (libc, -lc) SYNOPSIS         top #include #include i

man7.org

  • https://man7.org/linux/man-pages/man7/fifo.7.html
 

fifo(7) - Linux manual page

fifo(7) — Linux manual page fifo(7) Miscellaneous Information Manual fifo(7) NAME         top fifo - first-in first-out special file, named pipe DESCRIPTION         top A FIFO special file (a named pipe) is similar to a pipe, except that it is ac

man7.org

 

'Dev > System Programming' 카테고리의 다른 글

[IPC] Shared Memory - 가장 빠른 프로세스 간 통신  (0) 2026.02.27
'Dev/System Programming' 카테고리의 다른 글
  • [IPC] Shared Memory - 가장 빠른 프로세스 간 통신
onepaperhoon
onepaperhoon
한장훈님의 블로그 입니다.
  • onepaperhoon
    OnePaperHoon Blog
    onepaperhoon
  • 전체
    오늘
    어제
    • 분류 전체보기 (14)
      • Dev (14)
        • System Programming (2)
        • Linux (0)
        • CS (0)
        • Network, Protocol (0)
        • Grapics (11)
        • Web, App (0)
        • Design Pattern (1)
      • Projects (0)
      • TIL (0)
      • Life (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    cpp
    shared memory
    Vertex Shader
    IPC
    glfw
    Pipe
    싱글톤 패턴
    Process
    그래픽스
    shader
    3d
    C언어
    OpenGL
    graphicapi
    c++
    공유 메모리
    Game
    named pipe
    디자인 패턴
    graphics
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
onepaperhoon
FIFO (Named Pipe) : 프로세스 간 통신의 기본
상단으로

티스토리툴바