Inter Process Communication (IPC) - GeeksforGeeks
OS 내에서 실행 중인 독립된 프로세스들이 서로 데이터를 교환하고 정보를 공유하기 위해 사용하는 매커니즘을 말함
일반적으로 프로세스는 독립적인 메모리 공간을 가지고 있어서 다른 프로세스의 메모리에는 직접 접근할 수 없음
따라서 여러 프로세스가 협력하여 작업을 수행하거나 결과를 공유해야 할 경우 IPC 기법을 사용함
프로세스 간에 데이터를 교환하거나, 작업 순서를 맞추거나, 상태를 공유해야 하는 모든 상황
물이 흐르는 관처럼 선입선출(FIFO, First-In, First-Out) 구조의 큐(Queue) 형태로 데이터를 전달
한쪽 끝은 데이터를 쓰는(Write) 용도이고, 다른 한쪽 끝은 데이터를 읽는(Read) 용도로 사용
한 프로세스의 출력을 다른 프로세스의 입력으로 직접 전달하는 데 사용
[주요 특징]
파이프는 크게 두 가지 종류로 나뉘는데, Anonymous Pipe & Named Pipe 두 경우 생성 방식과 수명 관리 방식에서 차이가 있음
| 구분 | 익명 파이프 | Named Pipe (FIFO) |
|---|---|---|
| 파일 시스템에 존재 | X | O |
| 접근 범위 | 부모-자식 프로세스 | 이름을 아는 모든 프로세스 |
| 생성 시스템콜 | pipe() | mkfifo() 후 open() |
| 참조 시점 | pipe() 호출 시 | open() 호출 시 커널 버퍼 생성 |
| 수명 | 모든 fd 닫히면 소멸 | 열려 있는 프로세스가 모두 닫히면 버퍼 소멸, 이름은 남음 |
struct pipe_inode_info 구조체를 기반으로 한 파이프 버퍼close()하거나 종료될 때 참조 카운트가 0이 되면 커널이 자동 정리함익명 → 파일처럼 접근할 수 있는 경로가 없음
오직 생성한 프로세스의 메모리 (파일 디스크립터) 안에서만 접근 가능
파일 시스템에 이름이 등록되지 않아 ls 명령어로 볼 수 없음
[ 왜 이름이 필요 없는가?]
익명 파이프는 동시에 존재하는 두 프로세스 사이에서만 유효하기 때문에
파일시스템을 통해 다른 프로세스가 접근할 필요가 없음
파이프는 프로세스 종료 시 자동으로 닫히고 사라짐
[위치] ****커널 메모리 공간 내에 임시 버퍼 형태로 존재
[접근] 두 개의 파일 디스크립터를 통해 접근
pipe() 시스템 호출을 통해 생성되며,fork() 시스템 호출로 자식 프로세스를 생성하면 파이프의 FD들이 복사되어 통신 경로가 확립됨 // [c.f.]
int fd[2];
pipe(fd); // 익명 파이프 생성
// fd[0] → 읽기용(read end)
// fd[1] → 쓰기용(write end)
// 이 시점에서 부모 프로세스 하나만 존재하고, 파이프를 통해 데이터를 읽고 쓸 수 있음
if (fork() == 0) { // fork()는 새로운 자식 프로세스를 생성
// 자식: 읽기 전용
close(fd[1]);
read(fd[0], buf, sizeof(buf));
} else {
// 부모: 쓰기 전용
close(fd[0]);
write(fd[1], "data", 4);
}
```
`fd[0]` → 읽기용(read end)
`fd[1]` → 쓰기용(write end)
이 시점에서 부모 프로세스 하나만 존재하고, 파이프를 통해 데이터를 읽고 쓸 수 있음 (FIFO)close(fd[1]);read(fd[0], buf, sizeof(buf));close(fd[0]);write(fd[1], "data", 4);close(fd[0]), close(fd[1])를 하면커널은 파이프 생성 시 내부적으로 커널 메모리 버퍼를 만들고, 이 버퍼에 연결된
struct file 구조체 두 개(읽기/쓰기)를 할당
이 두 개의 구조체가 각각 fd[0], fd[1]과 연결됨
→ 이름이 없어도 fd만 공유하면 통신이 가능
fd는 커널 메모리에 존재하는 같은 파이프 객체를 가리키기 때문에 두 프로세스는 해당 객체를 통해 데이터를 주고 받을 수 있음
파일 시스템에 이름(파일 시스템 내의 엔트리, pathname)이 존재하며,
여러 프로세스들이 이 이름을 통해 임의로 데이터를 읽고 쓸 수 있는 파이프
[위치] 파일 시스템 내에 특수 파일 형태로 존재
데이터 자체는 익명 파이프처럼 커널 버퍼에 저장됨
[접근] 파일 시스템의 경로를 사용
open(), read(), write(), close() 등의 파일 입출력 함수를 사용할 수 있음// c.f
[terminal] mkfifo /tmp/myfifo
mkfifo("/tmp/myfifo", 0666); // FIFO 생성
// 부모 프로세스
int fd = open("/tmp/myfifo", O_WRONLY);
write(fd, "Hello", 5);
close(fd);
// 자식 프로세스
int fd = open("/tmp/myfifo", O_RDONLY);
char buf[100];
read(fd, buf, sizeof(buf));
close(fd);
open()하면 커널 내부에 파이프 객체(pipe_inode_info)가 생성됨/tmp/myfifo)으로 프로세스 간 통신 가능[파일 디스크립터 구조]
| 구성 요소 | 위치 | 설명 |
|---|
| 파일 디스크립터 번호
(fd: int) | 유저 공간 | 정수값
커널의 테이블 인덱스 역할 |
| 파일 디스크립터 테이블
(File Descriptor Table) | 커널 공간 (프로세스별) | 각 fd가 어떤 파일을 가리키는지 저장하는 포인터 배열 |
| Open File Table (struct file) | 커널 공간 (시스템 전역) | 실제 열린 파일의 상태 정보 (offset, flags 등) |
| Inode Table (struct inode) | 커널 공간 (파일시스템 계층) | 파일의 메타데이터 (권한, 크기, 디스크 블록 등) |
OS(주로 Unix / Linux 계열)에서 프로세스가 파일, 소켓, 파이프 등과 같은 입출력 자원에 접근하기 위해 사용하는 정수 기반의 식별자 (ID)
⇒ 프로세스가 어떤 파일이나 네트워크 자원과 연결되어 있는지를 구분하기 위한 번호표
open(), read(), write() 같은 시스템 호출(System Call)을 통해서만 커널에 요청할 수 있음 | 영역 | 접근 가능한 주체 | 내용 |
| --- | --- | --- |
| **유저 공간(User space)** | 애플리케이션 코드
(e.g. C 프로그램) | 코드, 변수, 스택, 힙 등 |
| **커널 공간(Kernel space)** | 운영체제 커널 코드만 접근 가능 | 시스템 콜, 파일, 네트워크, 디바이스 관리 | [메세지 큐]
커널 메모리에 존재하며, 메세지를 단위로 전송하고, 순서와 우선순위를 관리할 수 있는 데이터 구조
MSGMAX와 MSGMNB에 의해 크기가 제한되고, 큐가 꽉 차면 블로킹 혹은 에러 처리 방식으로 동작
| 파라미터 | 의미 |
|---|---|
MSGMAX | 한 메시지 최대 크기 |
MSGMNB | 메시지 큐 전체 최대 크기 (큐에 저장 가능한 총 메시지 바이트) |
MSGPOOL | 커널 전체 메시지 버퍼 총 용량 |
[FIFO와 다른점]
| 항목 | 파이프 / Named pipe | 메시지 큐 |
|---|---|---|
| 단위 | 바이트 스트림 | 메시지 단위 (mtype + mtext) |
| 데이터 순서 | FIFO | FIFO 또는 메시지 타입 우선 |
| 파일 시스템 존재 여부 | Named pipe만 존재 | 없음 (커널 메모리) |
| 동기화 | 쓰기/읽기 블로킹 | 커널 내부 큐로 자동 동기화, 블록 가능 |
| 여러 프로세스 | 가능하지만 데이터 섞임 | 메시지 타입으로 선택적 수신 가능 |
| 크기 제한 | 커널 버퍼 크기 | 큐 최대 크기(MSGMAX 등) |
파이프와 달리 바이트 스트림이 아니라
메시지 단위, 우선순위 선택 가능, 파일 이름 불필요가 큰 특징
[특징]
커널 메모리에 생성된 버퍼를 여러 프로세스가 가상 주소로 매핑하여 직접 읽고 쓰는 방식
속도는 빠르지만 동기화와 메모리 해제 관리가 중요함
[파이프 / 메세지 큐와 비교]
| 항목 | 파이프 / 메시지 큐 | 공유 메모리 |
|---|---|---|
| 데이터 전송 | 커널을 통해 전달 | 커널 메모리에 직접 매핑 |
| 속도 | 중간 (시스템 콜 필요) | 매우 빠름 |
| 데이터 단위 | 바이트 / 메시지 | 자유 (버퍼 크기만 제한) |
| 동기화 | 자동 블로킹 가능 | 프로세스 간 직접 관리 필요 |
| 여러 프로세스 | FIFO / 타입 순서 | 모든 프로세스가 동시에 접근 가능 |
| 수명 관리 | 커널이 관리 | 프로세스가 분리 후 필요 시 IPC_RMID로 제거 |
[특징]
원래 네트워크 통신을 위해 고안된 기술이지만, 같은 컴퓨터 내의 서로 다른 프로세스 간 통신에도 활용 가능
프로세스가 같은 머신에 있어도, 다른 머신에 있어도 동일한 코드 구조로 통신 가능
특히 클라이언트-서버 모델을 기반으로 하는 양방향 통신에 매우 유용
[소켓이란?]
네트워크 상에서 데이터를 송수신하기 위해 프로토콜, IP 주소, 포트 번호의 조합으로 정의되며
프로세스가 데이터를 주고받을 수 있는 인터페이스를 제공
[로컬 IPC에서의 소켓]
1. 인터넷 소켓 (Internet Socket)
AF_INET 주소 체계를 사용하여 IP 주소와 포트 번호를 기반으로 통신
데이터가 네트워크 스택(Network Stack)을 거치기 때문에 다른 IPC 방식에 비해 속도는 느릴 수 있지만, 통신 방식이 네트워크 통신과 동일하므로 확장성이 매우 높음
AF_UNIX 주소 체계를 사용하여 IP 주소 대신 파일 시스템의 경로(path)를 기반으로 통신
네트워크 스택을 거치지 않고 커널 내부에서 직접 처리되므로, 인터넷 소켓보다 훨씬 빠르며 로컬 IPC에서 효율적인 대안으로 사용됨
[장점]
| 구분 | TCP Socket | Unix Domain Socket |
|---|---|---|
| 범위 | 로컬 + 네트워크 | 로컬 호스트 전용 |
| 성능 | 상대적으로 느림 | 매우 빠름 |
| 설정 | IP + Port 필요 | 파일 경로 필요 |
| 연결 방식 | connect → accept | connect → accept |
| 신뢰성 | TCP 사용시 보장 | 스트림 기반, 커널에서 처리 |
Unix Domain Socket은 로컬 IPC에 최적화되어, TCP/IP보다 오버헤드가 적음
TCP 소켓을 쓰면 로컬 프로세스끼리도 TCP/IP를 통해 통신 가능하지만, 약간 느림