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