IPC 란?
IPC는 프로세스들 사이에 서로 데이터를 주고 받는 방식, 즉 프로세스 간의 통신을 의미한다. 각 프로세스는 독립적인 실행 객체이기 때문에 프로세스 간 통신을 하려면 커널이 제공하는 IPC 모델 방식을 사용해야 한다.
IPC 의 필요성
- 프로세스들은 서로 독립적인 메모리 영역을 가지고 실행됨
- 다른 프로세스의 영향을 받지 않지만 독립되어 있기 때문에 별도의 설비가 없이는 프로세스 서로간의 통신이 어렵다는 단점이 있음
- 하나의 프로그램이지만 여러 프로세스 간의 협력이 필요한 경우가 있음
- 특정 Task를 여러 개의 Sub Task로 나누어 더 빠르게 수행해야 하는 경우
- 동시에 많은 Task를 한 번에 처리해야 하는 경우
- 프로세스 간의 통신이 필요한 경우를 위해 운영체제 커널영역에서 IPC 를 제공함
IPC 는 크게 두가지 모델로 나뉜다. 공유 메모리 모델과 메세지 전달 모델 이다.
공유 메모리 모델
- 프로세스가 공유 메모리 할당을 커널에 요청하면, 커널은 해당 프로세스에 메모리 공간을 할당해 준다.
- 이후 어떤 프로세스건 해당 메모리 영역에 접근할 수 있다.
- 공유 메모리가 설정되면, 그 이후의 통신은 커널의 관여 없이 진행이 가능하다.
- 두 개 이상의 프로세스들이 주소 공간의 일부를 공유하며, 공유한 메모리 영역에 읽기/쓰기를 통해 통신을 수행한다. (Read and Write)
장점
- 커널의 관여 없이 메모리를 직접 사용하여 빠르게 IPC 통신이 가능하다.
- 프로그램 레벨에서 통신 기능을 제공하여, 자유로운 통신이 가능하다.
단점
- 메시지 전달 방식이 아니기에 데이터를 읽어야 하는 시점을 알 수 없다.
- 때문에 별도의 동기화 기술이 필요하다.
- 동시에 같은 메모리 위치를 접근하는 경우가 발생할 수 있기 때문에 공유 메모리에 접근할 프로세스 간의 Lock 메커니즘이 필요하다.
- 커널 설정에 종속적이기 때문에 사용하기 전 커널에서 사용하고 있는 공유 메모리 사이즈를 확인해야 한다.
공유 메모리 모델 예
- POSIX: Portable OS interface (for UNIX)
- 공유 메모리 (Shared Memory)
메세지 전달 모델
- 커널 메모리 영역에 메시지 전달을 위한 채널을 만들어서 협력하는 프로세스들 사이에 메시지 형태로 정보를 Send/Receive 하는 방법
- 커널을 경유하여 메시지를 송/수신자끼리 주고 받으며, 커널에서는 데이터를 버퍼링한다.
- 프로세스 간 메모리 공유 없이 동작이 가능하다.
장점
- 커널에서 데이터의 주고 받는 것을 컨트롤할 수 있어 별도의 동기화 로직이 필요하지 않다.
단점
- 커널을 통해서 데이터를 주고 받기 때문에 Shared Memory 모델보다 느리다.
Direct Communication
- 통신하려는 프로세스의 이름을 명시적으로 표시하여 메시지를 직접 전달하는 방식이다.
- 프로세스 간 링크는 유일
- 대부분 양방향으로 구성됨
- A 프로세스가 B 프로세스에게 메시지를 전달하고 싶을 때, 커널에게 직접적으로 수신자 A 프로세스가 메시지를 전달한 후 커널이 B 프로세스에게 해당 메시지를 전달
Indirect Communication
- port로 전송만 하면 되기 때문에 복잡한 Communication Link를 만들 수 있으며, 다대다 관계가 가능하다.
- A 프로세스가 B 프로세스에게 메시지를 전달하고 싶을 때, 커널 내부 특정 포트에 메시지를 저장해 놓고, B 프로세스가 해당 포트에 접근하여 메시지를 전달
메세지 전달 모델 예시
파이프
- 주로 부모 자식간의 단방향 통신에 사용됨
- 1:1 통신, 한 방향으로만 데이터가 이동함
- 두 개의 프로세스를 파이프로 연결하여 하나의 프로세스는 데이터를 쓰기만 하고 다른 프로세스는 데이터를 읽기만!
- 만약 읽기/쓰기, 즉 송/수신을 모두 하기 원한다면 두 개의 파이프를 만들어야
- 용량 제한이 있기 때문에 파이프가 가득 차면 더 이상 쓸 수 없다.
- 읽는 쪽과 쓰는 쪽이 정해져 있는 단순한 데이터 흐름에 적합하다.
- read()와 write()가 기본적으로 block mode로 작동되기에 프로세스가 read 대기중이라면 read가 끝나기전에는 write를 할 수 없다.
- 스트림 기반으로 작동
- pipes 에 접근하는 것은 File Descriptors를 읽거나 쓰는 것으로 가능하다.
> ps -aux | grep root | tail
- shell 명령어 예시
- '|' 를 이용한 pipelined 명령은 pipes를 이용한 것이다. ps -aux의 출력결과를 grep root 의 입력으로 사용하고, 또 그것의 결과를 tail의 입력으로 사용하는 식이다.
메세지 큐
- 메세지(패킷) 단위로 작동
- Named PIPE는 데이터의 흐름이라면 Message Queue는 메모리 공간이라는 점
- 부모/자식 관계가 아니더라도, 어느 프로세스 간의 데이터 송수신이 가능하다.
- 양방향 통신이 가능하며, 메시지의 형태는 사용자가 정의하여 사용할 수 있다.
- Message Queue에 쓸 데이터에 번호를 붙임으로써 다수의 프로세스가 동시에 데이터를 쉽게 다룰 수 있다.
- 비동기 방식이기에 방대한 처리량이 있다면 큐에 넣은 후 나중에 처리할 수 있다.
- 데이터가 많이 쌓일 수록 추가적인 메모리 자원이 필요하며, 큐에 데이터를 넣고 나오는 과정에서 오버헤드 발생 가능
소켓
- 네트워크 소켓을 이용하여 Client - Server 구조로 데이터 통신을 하며, 원격에서 프로세스 간 데이터를 공유할 때 사용
- 프로세스는 포트 번호를 이용하여 통신하려는 상대 프로세스의 소켓을 찾음
- 범용적인 IPC로서 양방향 통신이 가능
- 포트의 도움으로, 다른 IPC와 달리 프로세스의 위치에 독립적이며, 다른 IPC는 모두 local에서만 사용할 수 있는 반면, Machine Boundary와 관계가 없기 때문에 Local 또는 Remote로 사용할 수 있다.
- 패킷 단위로 주고 받음으로써 직관적으로 이해하기 쉬운 코드를 만들 수 있다.
- Internet UDP와는 달리 경로를 지정할 수는 없다.
- 서버 단에서는 bind, listen, accept을 진행하여 소켓 연결을 위한 준비를 하고, 클라이언트 단에서는 connect를 통해 서버에 요청하고 연결이 수립된 후, socket에 send함으로써 데이터를 주고 받는다.
소켓
socket은 네트워크 상에서 통신하기 위한 종단점으로 추상화된 개념이다.
소켓 통신은 흔히 네트워크 통신 기법으로 많이 사용되는 방법으로, 양쪽 PC에서 각각 임의의 포트를 정하고 해당 포트 간의 대화를 통해 데이터를 주고 받는 방식이다.
소켓이 네트워크 기능을 담고 있다 보니 네트워크 기능을 이용해 IPC로도 사용할 수 있다. 즉, 소켓을 한 PC 내 두 개의 프로세스 간 통신 기법으로도 사용이 가능하다. 기존의 네트워크 상에서 소켓 통신과 달라지는 점은 sock_addr_in 구조체를 sock_addr_un으로 변경하고, 속성을 AF_INET에 대해 AF_UNIX로 변경한 뒤 소켓 통신을 하기 위한 파일 경로가 필요하다고 한다.
Reference
[운영체제] IPC
[운영체제] IPC Inter-Process Communication