프로세스 간 통신 (IPC, Inter Process Communication)

한눈에 보기

독립된 주소 공간을 가진 프로세스들이 데이터를 주고받는 IPC를 다룬다. 메시지 전달과 공유 메모리 모델, 파이프와 메시지 큐와 소켓 등 기법 비교, 파이프 코드 예시와 실무 선택 기준까지 정리한다.

최종 업데이트 2026.09.17

프로세스 간 통신(IPC, Inter Process Communication)은 서로 독립된 주소 공간을 가진 프로세스들이 데이터를 주고받기 위해 운영체제가 제공하는 메커니즘의 총칭이다. 프로세스는 기본적으로 서로의 메모리에 접근할 수 없으므로, 협력이 필요하면 파이프, 공유 메모리, 메시지 큐, 소켓 같은 커널이 중개하는 통로를 써야 한다. 어떤 방식을 고르느냐에 따라 성능, 동기화 부담, 사용 범위가 크게 달라진다.

왜 IPC가 필요한가

운영체제는 보호를 위해 프로세스마다 독립된 가상 주소 공간을 부여한다. 한 프로세스의 포인터는 다른 프로세스에서 아무 의미가 없고, 이 격리 덕분에 한 프로세스의 버그가 다른 프로세스를 망가뜨리지 못한다. 그러나 셸의 파이프라인처럼 한 프로그램의 출력을 다른 프로그램의 입력으로 잇거나, 브라우저처럼 렌더러 프로세스와 메인 프로세스가 협력하거나, 여러 워커가 작업을 나눠 처리하는 구조에서는 프로세스 사이에 데이터가 오가야 한다. IPC는 이 격리를 유지하면서 통제된 방식으로만 벽에 구멍을 내 주는 장치다.

두 가지 큰 모델: 메시지 전달과 공유 메모리

IPC는 크게 메시지 전달(message passing) 모델과 공유 메모리(shared memory) 모델로 나뉜다. 메시지 전달은 send와 receive 연산으로 커널을 거쳐 데이터를 복사하는 방식이다. 커널이 큐잉과 동기화를 대신해 주므로 사용이 쉽지만, 데이터가 사용자 공간에서 커널로, 다시 상대 사용자 공간으로 복사되는 비용이 든다. 공유 메모리는 두 프로세스의 페이지 테이블이 같은 물리 페이지를 가리키게 매핑한 뒤, 이후에는 커널 개입 없이 메모리 읽기와 쓰기로 직접 통신하는 방식이다. 복사가 없어 대량 데이터에 가장 빠르지만, 동시 접근을 막는 동기화(세마포어나 뮤텍스)를 사용자가 직접 책임져야 한다. 소량의 제어 메시지는 메시지 전달로, 대용량 데이터는 공유 메모리로 처리하는 조합이 흔하다.

주요 IPC 기법 비교

기법통신 형태범위특징
익명 파이프(Anonymous Pipe)단방향 바이트 스트림부모 자식 등 혈연 관계 프로세스셸의 | 가 이것이며 생성이 간단하다
명명 파이프(Named Pipe, FIFO)단방향 바이트 스트림같은 호스트의 임의 프로세스파일 시스템 경로로 식별한다
메시지 큐(Message Queue)경계 있는 메시지같은 호스트메시지 단위와 우선순위를 지원한다
공유 메모리(Shared Memory)메모리 직접 접근같은 호스트가장 빠르지만 동기화를 직접 해야 한다
시그널(Signal)번호 하나의 비동기 통지같은 호스트데이터 전달보다 사건 통지에 쓰인다
유닉스 도메인 소켓(Unix Domain Socket)양방향 스트림 또는 데이터그램같은 호스트소켓 API 그대로 쓰며 파일 디스크립터 전달도 가능하다
네트워크 소켓(Network Socket)양방향, TCP나 UDP원격 호스트 포함유일하게 머신 경계를 넘는 범용 수단이다

파이프 사용 예시

부모가 자식에게 데이터를 보내는 전형적인 파이프 코드는 다음과 같다. 파이프는 읽기용과 쓰기용 파일 디스크립터 한 쌍으로 만들어지고, fork 이후 각자가 쓰지 않는 쪽 끝을 닫는 것이 관례다. 파이프는 커널 안의 고정 크기 버퍼로 구현되어 있어서, 버퍼가 가득 차면 쓰는 쪽이 블로킹(blocking)되고 버퍼가 비면 읽는 쪽이 블로킹된다. 이 흐름 제어 덕분에 생산 속도와 소비 속도가 달라도 자연스럽게 조율되며, 셸 파이프라인에서 빠른 명령이 느린 명령을 기다리게 되는 이유이기도 하다. 쓰기 끝이 모두 닫힌 파이프에서 read는 0을 반환해 EOF를 알리고, 읽기 끝이 닫힌 파이프에 write하면 SIGPIPE 시그널을 받는다.

int fd[2];
pipe(fd);                 // fd[0]: 읽기, fd[1]: 쓰기
pid_t pid = fork();
if (pid == 0) {           // 자식: 읽는 쪽
    close(fd[1]);
    char buf[128];
    ssize_t n = read(fd[0], buf, sizeof(buf));
    // n 바이트 처리
} else {                  // 부모: 쓰는 쪽
    close(fd[0]);
    write(fd[1], "hello", 5);
    close(fd[1]);         // 닫으면 자식의 read가 0(EOF)을 받는다
}

선택 기준과 실무 감각

기법 선택은 몇 가지 질문으로 정리된다. 통신 상대가 같은 머신에 있는가, 데이터가 스트림인가 메시지 단위인가, 처리량이 중요한가 지연이 중요한가, 상대 프로세스와 생성 관계가 있는가다. 같은 호스트의 서비스 간 통신에는 유닉스 도메인 소켓이 TCP 루프백보다 오버헤드가 적어 널리 쓰이고(도커 데몬의 소켓이 대표적이다), 고성능 데이터 교환에는 공유 메모리 위에 링 버퍼(ring buffer)를 얹는 구조가 흔하다. 분산 환경이라면 결국 네트워크 소켓 위의 gRPC나 메시지 브로커 같은 상위 프로토콜로 올라가게 된다. 스레드 간 통신과 달리 IPC는 커널 경유 비용이나 매핑 관리가 따르므로, 애초에 프로세스 분리가 필요한지부터 따지는 것이 설계의 출발점이다.

면접에서 이렇게 물어본다

  • 공유 메모리 방식과 메시지 전달 방식의 장단점을 복사 비용과 동기화 관점에서 비교해 보라.
  • 익명 파이프와 명명 파이프의 차이는 무엇이고 각각 언제 쓰는가.
  • 공유 메모리를 쓸 때 별도의 동기화 도구가 반드시 필요한 이유를 설명해 보라.
  • 같은 호스트의 두 데몬이 통신할 때 유닉스 도메인 소켓이 TCP 루프백보다 유리한 점은 무엇인가.
  • 셸에서 명령어 A | B 를 실행하면 내부적으로 어떤 IPC가 어떻게 구성되는지 설명해 보라.
운영체제 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기