IPC - 프로세스간 통신
프로세스는 독립적으로 실행한다. 다른 프로세스의 데이터에 접근하려 해도 memory protection에서 접근하지 못하게 한다. 이처럼 독립적인 프로세스가 서로 통신하기 위한 방법이 무엇인지 살펴보자.
통신 방식
프로세스가 서로 통신하는 방식은 크게 2가지이다.
- Shared Memory
- Message Passing
Shared Memory
두 개 이상의 프로세스 들이 주소 공간의 일부를 공유하여 읽기 쓰기를 수행한다. 공유 메모리가 설정되면 커널의 관여없이 직접 읽고 쓸 수 있기 때문에 속도가 빠르다. 다른 프로세스의 변경 사항을 알기 위해 동기화가 필요하며, 한 번에 한 프로세스가 접근하는 접근 제어가 필요하다. 접근 제어 방식으로는 semaphore 등이 있다.
Message Passing
한 프로세스에서 협력하는 다른 프로세스로 커널을 통해 메시지를 주고(send) 받는(receive) 방식이다. Message Passing 방식으로는 PIPE, Message Queue, Socket, Signal 등이 있다.
- 파이프(PIPE)
파이프는 통신을 위한 메모리 공간(버퍼)를 생성하고 버퍼를 통해 데이터를 전달하는데, 한 방향으로만 전달 가능하다. 다시 말해, 한 쪽 프로세스(A)는 보내기만 다른 한 쪽(B)은 받기만 가능한 것이다. 데이터를 서로 주고 받기 위해서는 A → B방향 파이프, B → A 방향 파이프 2개 연결해야 한다. 또한 여러 개 프로세스가 접근하지 못한다. 그렇기 때문에 프로세스가 많을수록 파이프 수도 증가하며 메모리 공간을 많이 차지하게 된다.
파이프는 Anonymous PIPE와 Named PIPE로 나뉜다.
- Anonymous PIPE
관련없는 외부 프로세스에서는 사용하지 못하는, 부모 프로세스와 자식 프로세스 간에 사용하는 PIPE
- Named PIPE
외부 프로세스에 간 통신에서 사용하는 PIPE
- 메세지 큐(Message Queue)
고정된 크기의 메시지를 연결 리스트를 이용하여 통신하는 방법이다. Message Queue에는 여러 프로세스가 접근 가능하며 동기화가 필요하다.
- 소켓(Socket)
상대 프로세스의 소켓으로 통신하며, 포트 번호를 통해 소켓을 찾아간다. 다른 IPC는 로컬에서만 사용 가능한 반면, 소켓은 로컬과 리모트 서버 모두 통신 가능하다.
- 시그널(Signal)
특정 이벤트가 발생했을 때 프로세스에게 시그널을 전달할 수 있다. 예를 들어, 자식 프로세스가 종료되었거나 오류가 발생했을 때, 인터럽트가 발생했을 때 그 정보를 알리는 시그널을 전달한다. 시그널은 여러 종류가 있으며 시그널 별로 번호가 붙어있다. 시그널 핸들러를 통해 특정 시그널에 대한 함수를 실행할 수 있다.