IPC (Inter-Process Communication, 프로세스 간 통신) - 3. 프로세스 간 데이터를 공유하는 방법

2025. 2. 8. 13:37정보기술/운영체제 (OS)

3️⃣ 프로세스 간 데이터를 공유하는 방법 (공유 메모리, 파일, 파이프)

운영체제에서 여러 프로세스가 데이터를 주고받아야 할 때, 데이터 공유 방식을 선택하는 것이 중요합니다. 프로세스 간 데이터를 공유하는 대표적인 방법으로는 공유 메모리(Shared Memory), 파일을 통한 교환, 파이프(Pipe) 가 있습니다. 각각의 방식은 속도, 사용 용도, 동기화 문제 등에서 차이가 있습니다.


📌 1️⃣ 공유 메모리 (Shared Memory)

공유 메모리는 운영체제가 할당한 특정 메모리 영역을 여러 프로세스가 공동으로 사용할 수 있도록 하는 방식입니다. 이를 통해 프로세스들은 빠르게 데이터를 주고받을 수 있습니다.

🔹 동작 방식

  • 운영체제는 공유 메모리 영역을 생성하고, 특정 프로세스들이 이 영역에 접근할 수 있도록 허용합니다.
  • 데이터를 메모리에 직접 읽고 쓰기 때문에 속도가 매우 빠름.
  • 하지만 동기화(Synchronization) 문제가 발생할 수 있어 세마포어(Semaphore)나 뮤텍스(Mutex)를 이용해 관리해야 함.

📌 비유: 공동 작업 문서

➡️ 여러 명이 공동 문서(Google Docs)를 함께 편집하는 것과 비슷합니다.
➡️ 문서를 직접 수정할 수 있어 빠르게 작업할 수 있지만, 동시에 여러 사람이 수정하면 충돌이 발생할 수 있습니다.
➡️ 따라서 편집 권한을 조정하거나 잠금 기능(뮤텍스)을 활용해야 합니다.

✅ 사용 사례

  • 데이터베이스와 애플리케이션 간 빠른 데이터 교환
  • 대용량 이미지, 영상 처리 시스템
  • 멀티프로세스 기반의 고성능 서버

🚀 예제 코드 (C 언어)

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <string.h>

int main() {
    int shmid = shmget(1234, 1024, IPC_CREAT | 0666); // 공유 메모리 생성
    char *data = (char *)shmat(shmid, NULL, 0); // 메모리 연결

    strcpy(data, "Hello from Shared Memory!"); // 데이터 저장
    printf("Shared Memory Data: %s\n", data);

    shmdt(data); // 공유 메모리 분리
    return 0;
}

📌 2️⃣ 파일을 통한 데이터 교환

파일을 이용한 데이터 교환은 가장 간단하고 널리 사용되는 IPC 방식 중 하나입니다. 하나의 프로세스가 파일에 데이터를 쓰고, 다른 프로세스가 파일을 읽어서 데이터를 공유하는 방식입니다.

🔹 동작 방식

  • 한 프로세스가 파일을 생성하여 데이터를 저장.
  • 다른 프로세스가 해당 파일을 읽어 데이터를 가져감.
  • 운영체제의 파일 시스템을 이용하기 때문에 데이터의 영속성이 보장됨.
  • 하지만 파일을 디스크에 저장하는 과정이 포함되어 속도가 상대적으로 느림.

📌 비유: USB를 이용한 데이터 공유

➡️ 한 사람이 USB에 파일을 저장하고, 다른 사람이 이를 가져와 확인하는 방식과 유사합니다.
➡️ 데이터를 직접 공유하는 것이 아니라 중간 저장소(파일 시스템)를 거쳐야 하므로 속도가 느림.
➡️ 하지만 파일은 시스템이 종료되어도 유지되므로, 안정적인 데이터 저장 방식입니다.

✅ 사용 사례

  • 로그 파일을 통한 데이터 기록 및 공유
  • 클라우드 스토리지 서비스 (예: Google Drive, Dropbox)
  • 프로세스 간 설정 파일 공유

🚀 예제 코드 (Python)

# 데이터 저장 프로세스
with open("shared_data.txt", "w") as f:
    f.write("Hello from File!")

# 데이터 읽기 프로세스
with open("shared_data.txt", "r") as f:
    data = f.read()
    print("Read from File:", data)

📌 3️⃣ 파이프 (Pipe)

파이프(Pipe)는 프로세스 간 한 방향(또는 양방향)으로 데이터를 전달하는 통로입니다.
운영체제는 파이프를 생성하여 두 개의 프로세스가 한쪽에서 데이터를 쓰고, 다른 한쪽에서 읽을 수 있도록 합니다.

🔹 동작 방식

  • 익명 파이프(Anonymous Pipe): 부모-자식 프로세스 간 통신에 주로 사용됨.
  • 명명된 파이프(Named Pipe, FIFO): 독립적인 프로세스 간에도 사용 가능.

📌 비유: 공장의 컨베이어 벨트

➡️ 생산 공장에서 컨베이어 벨트를 통해 부품을 전달하는 것과 비슷합니다.
➡️ 한쪽에서는 데이터를 넣고, 다른 쪽에서는 이를 가져갑니다.
➡️ 방향이 정해져 있기 때문에 데이터 흐름이 일방적입니다.

✅ 사용 사례

  • 리눅스 명령어 파이프 (|)
    ls | grep "test"  # ls 출력 결과를 grep에 전달
    
  • 부모 프로세스와 자식 프로세스 간 통신
  • 멀티프로세스 기반 시스템에서 스트리밍 데이터 전송

🚀 예제 코드 (C 언어)

#include <stdio.h>
#include <unistd.h>

int main() {
    int fd[2]; // 파일 디스크립터 배열
    pipe(fd);  // 파이프 생성
    pid_t pid = fork(); // 자식 프로세스 생성

    if (pid == 0) { // 자식 프로세스 (읽기)
        close(fd[1]); // 쓰기 닫기
        char buffer[100];
        read(fd[0], buffer, sizeof(buffer));
        printf("Child received: %s\n", buffer);
        close(fd[0]);
    } else { // 부모 프로세스 (쓰기)
        close(fd[0]); // 읽기 닫기
        write(fd[1], "Hello from Parent!", 18);
        close(fd[1]);
    }
    return 0;
}

📌 정리

✔️ 공유 메모리(Shared Memory)
✅ 빠른 데이터 공유 가능
✅ 동기화 문제가 발생할 수 있음 (세마포어, 뮤텍스 필요)
✅ 예: 데이터베이스, 그래픽 프로세싱

✔️ 파일을 통한 데이터 교환
✅ 저장된 데이터가 유지됨
✅ 디스크 접근으로 인해 속도가 느림
✅ 예: 로그 파일, 클라우드 스토리지

✔️ 파이프(Pipe)
✅ 프로세스 간 실시간 데이터 전송 가능
✅ 한 방향 통신 (익명 파이프), 독립 프로세스 간 통신 가능 (명명된 파이프)
✅ 예: 리눅스 명령어 파이프, 부모-자식 프로세스 통신