테마
프로세스 간 통신
프로세스(process)는 서로의 메모리를 볼 수 없다. 그래서 두 프로세스가 데이터를 주고받으려면 커널(kernel)이 마련한 통로를 거쳐야 하고, 이 방법들을 묶어 IPC(Inter-Process Communication, 프로세스 간 통신)라고 한다. 방식마다 "커널이 데이터를 대신 옮겨 주느냐, 같은 메모리를 함께 보게 해 주느냐"가 다르고, 이 차이가 속도와 사용 난이도를 가른다.
왜 따로 통신 방법이 필요한가
운영체제는 프로세스마다 독립된 주소 공간(address space)을 준다. 주소 공간은 프로세스가 쓸 수 있는 주소의 전체 범위다. 한 프로세스가 가리키는 주소 1000번지는 다른 프로세스의 1000번지와 전혀 다른 실제 메모리다. 이 격리 덕분에 한 프로그램의 버그가 다른 프로그램의 데이터를 망치지 못한다. 대신 협력하려면 경계를 넘는 공식 통로가 필요하다. 같은 프로세스 안의 스레드(thread)는 메모리를 공유하므로 이런 통로 없이 변수로 바로 주고받는다.
두 가지 모델
IPC는 크게 두 모델로 나뉜다.
다이어그램 로딩…
- 메시지 전달(message passing): 보내는 쪽이 시스템 콜(system call)로 데이터를 커널에 넘기면, 커널이 이를 보관했다가 받는 쪽에 복사해 준다. 커널이 메시지를 들어온 순서대로 넘겨 주고, 받을 데이터가 아직 없으면 받는 쪽을 기다리게 해 주므로 쓰기 쉽다. 대신 주고받을 때마다 시스템 콜과 복사 비용이 든다. 파이프(pipe)·메시지 큐(message queue)·소켓(socket)이 이 모델이다.
- 공유 메모리(shared memory): 커널이 같은 물리 메모리 영역을 두 프로세스의 주소 공간에 함께 붙여 준다. 한 번 붙인 뒤에는 커널을 거치지 않고 일반 메모리처럼 읽고 쓰므로 가장 빠르다. 대신 두 프로세스가 같은 곳을 동시에 고치면 결과가 꼬이므로, 세마포어(semaphore) 같은 도구로 직접 동기화해야 한다.
파이프
파이프는 한쪽 끝에 쓴 바이트를 다른 쪽 끝에서 순서대로 읽는 한 방향 통로다. pipe() 시스템 콜은 읽기용과 쓰기용 파일 디스크립터(file descriptor) 두 개를 돌려준다. 이름이 없으므로 익명 파이프(anonymous pipe)라고도 하며, 그 디스크립터를 물려받은 프로세스끼리만 쓸 수 있다. 보통 부모가 파이프를 만든 뒤 fork()로 자식을 만들어 나눠 쓴다. 셸(shell, 명령을 입력받아 프로그램을 실행해 주는 프로그램)에서 ls | grep txt라고 치면 셸이 파이프를 만든 뒤 두 자식 프로세스를 띄워, 형제끼리 파이프를 나눠 쓰게 한다.
파이프에는 메시지 경계가 없다. 100바이트를 두 번 써도 받는 쪽은 200바이트짜리 흐름으로 읽을 수 있다. 읽을 데이터가 없으면 read가 기다리고, 커널의 파이프 버퍼가 가득 차면 write가 기다린다. 양방향으로 주고받으려면 파이프를 두 개 만든다.
이름 있는 파이프(named pipe)는 mkfifo로 파일 시스템(file system)에 이름을 붙인 파이프다. FIFO(First In First Out, 선입선출)라고도 부른다. 이름이 있으므로 서로 무관하게 따로 실행된 프로세스도 권한만 있으면 그 경로를 열어 쓸 수 있다. 경로는 파일 시스템에 있지만 데이터는 디스크에 기록되지 않고 커널 안에서만 오간다.
메시지 큐
메시지 큐는 커널이 관리하는 대기열에 메시지를 하나씩 넣고 꺼내는 방식이다. 파이프와 달리 메시지 경계가 유지된다. 100바이트 메시지를 넣으면 받는 쪽도 정확히 100바이트 메시지 하나를 꺼낸다. POSIX(Portable Operating System Interface, 이식 가능 운영체제 인터페이스) 메시지 큐는 메시지마다 우선순위를 붙일 수 있고, 우선순위가 높은 메시지가 먼저 나온다. 또 만든 프로세스가 끝나도 지우거나 시스템이 꺼질 때까지 남는다. 그래서 보내는 쪽이 먼저 끝나도 나중에 실행된 프로세스가 메시지를 꺼낼 수 있지만, 다 쓴 큐는 직접 지워야 커널 자원이 남지 않는다.
이어지는 내용은 프로세스 간 통신 2에서 다룬다. 네트워크 너머까지 쓰는 소켓, 사건만 알리는 시그널(signal), 그리고 방식별 비교와 선택 기준을 본다.
면접 포인트
- "IPC가 왜 필요한가요?" → 프로세스마다 주소 공간이 분리돼 서로의 메모리를 직접 볼 수 없어서.
- "공유 메모리와 메시지 전달의 차이는?" → 공유 메모리는 붙인 뒤 커널을 안 거쳐 가장 빠르지만 동기화를 직접 해야 한다. 메시지 전달은 커널이 복사·순서를 맡아 쉽지만 호출마다 비용이 든다.
- "익명 파이프와 이름 있는 파이프의 차이는?" → 익명 파이프는 디스크립터를 물려받은 프로세스끼리만, FIFO는 경로로 무관한 프로세스도 연다.
- "파이프와 메시지 큐의 차이는?" → 파이프는 경계 없는 바이트 흐름, 메시지 큐는 메시지 경계와 우선순위가 있다.
