hongcheol / CS-study

cs지식을 정리하는 공간
MIT License
248 stars 30 forks source link

IPC(Inter-Process Communication) #109

Open psi1104 opened 3 years ago

psi1104 commented 3 years ago

IPC는 프로세스들 간에 데이터를 주고 받는 통신 또는 그 방법입니다.

프로세스는 각각 OS로부터 할당받은 독립된 메모리 공간에서 실행됩니다. 하지만 정보 공유, 분산 처리로 작업 속도 향상, 시스템 기능 모듈화 등을 위해서 데이터를 공유하거나 서로 통신이 필요할 때가 있습니다. 이때 사용할 수 있도록 커널에서 여러 방식의 IPC를 제공합니다.

IPC 는 크게 Message Passing(메시지 전달) 방식Shared Memory(공유 메모리) 방식이 있습니다.

Message Passing(메시지 전달 방식)

Message Passing은 memory protection을 위해 OS가 커널 내부에 메시지를 기록할 수 있는 공간을 마련해 두어서 receive와 send 시스템 콜을 이용하여 메시지를 커널이 대리 전달합니다. 따라서 OS의 간섭이 지속적으로 필요합니다. 같은 곳을 읽고 쓰는 것이 아니므로 동기화 문제가 발생하지 않으나 커널을 거쳐야 하기 때문에 시간이 오래 걸려 성능이 좋지 않습니다. 또한 시스템 콜을 매번 사용하므로 오버헤드 발생할 수 있습니다.

PIPE (익명 PIPE)

파이프는 두 개의 프로세스를 연결하는 1:1 통신입니니다. 이때, 하나의 프로세스는 데이터를 쓰기만 다른 하나는 데이터를 읽기만 하는 단방향 통신만 가능합니다. 한쪽 방향으로만 통신이 가능한 파이프의 특징 때문에 Half-Duplex(반이중) 통신이라고 부르기도 합니다.

PIPE와 같은 반이중 통신의 경우 하나의 통신선로는 읽기나 쓰기 중 하나만 가능하므로 만약 읽기와 쓰기, 즉 송/수신을 모두 하기 원한다면 두개의 파이프를 만들어야 합니다.

read()와 write()가 기본적으로 block mode로 작동되기에 프로세스가 read 대기 중이라면 read가 끝나기 전에 write를 할 수 없습니다.

부모-자식 프로세스

프로세스는 실행되는 도중 시스템 콜을 통해 새로운 프로세스를 생성할 수 있습니다.

다른 프로세스를 생성한 프로세스를 부모 프로세스, 생성 된 프로세스를 자식 프로세스라고 합니다.

Named PIPE(FIFO)

익명 파이프(Pipe)는 부모-자식 프로세스와 같이 통신을 할 프로세스를 명확하게 알 수 있는 경우 사용합니다. 이에 반해, Named PIPE는 프로세스 통신을 위해 이름이 있는 파일을 사용하기 때문에 전혀 모르는 상태의 프로세스들 사이의 통신에서도 사용합니다.

Named PIPE의 생성은 mkfifo를 통해 이뤄지는데, mkfifo가 성공하면 명명된 파일이 생성됩니다.

PIPE 방식은 모두 먼저 입력된 데이터가 먼저 전달되는 흐름을 가진다는 측면에서 동일한 데이터 흐름 메커니즘을 가집니다.

Message Queue

Message Queue는 고정된 크기를 갖는 메시지의 연결 리스트를 이용한 메시지 단위의 통신입니다. 메세지의 형태는 사용자가 정의할 수 있으며, 통신하고자 하는 프로세스 간에 정의가 필요합니다. 입출력 방식으로 보자면 위의 Named PIPE와 동일하다고 볼 수 있지만, Name PIPE가 데이터의 흐름이라면 Message Queue는 메모리 공간이라는 차이가 있습니다.

Message Queue 는 어디에서나 물건을 꺼낼 수 있는 컨테이너 벨트라고 볼 수 있습니다. Message Queue에 쓸 데이터에 번호를 붙임으로써 여러 개의 프로세스가 동시에 데이터를 쉽게 다룰 수 있습니다.

Socket

Socket은 일반적으로 두 네트워크 프로그램 사이에서 데이터의 입출력의 관문, 또는 그를 위한 운영체제의 API로 많이 쓰입니다. 파이프 관점을 네트워크로 확장한 것으로 생각할 수 있습니다. 그래서 프로세스들 사이의 통신에서도 OS가 제공하는 Port를 통해 사용할 수 있습니다.

Shared Memory(공유 메모리 방식)

다수의 프로세스가 동시에 작동하는 Linux 운영체제의 특성상 프로세스의 메모리 영역은 반드시 보호되어져야 합니다. 그렇지만 메모리 영역에 있는 데이터를 다른 프로세스도 사용할 수 있도록 해야하는 경우도 있습니다. Thread에서 처럼 메모리 영역을 공유한다면 더 편하게 데이터를 함께 사용할 수 있을 것입니다.

Shared Memory(공유 메모리)는 프로세스간 메모리 영역을 공유해서 사용할 수 있도록 허용합니다. 프로세스가 공유 메모리 할당을 커널에 요청하면 커널은 해당 프로세스에 메모리 공간을 할당해줍니다. 이후 접근할 프로세스들이 규약을 정해서 해당 메모리 영역에 접근할 수 있습니다.

공유메모리는 커널이 처음 생성하지만 이후에 커널의 도움 없이 곧바로 메모리에 접근할 수 있기 때문에 다른 모든 IPC들 중에서 가장 빠르게 작동할 수 있습니다. 하지만, Producer-Consumer Problem 같은 동기화 문제가 생길 수 있기 때문에 Semaphore 등으로 해결해야 합니다.

Producer-Consumer Problem

정보를 생산하는 Producer와 정보를 소비하는 Consumer 프로세스가 있다. 이 두 프로세스는 같은 공간을 공유한다. 두 프로세스가 생산과 소비를 반복하면서 문제가 발생할 수 있다.

  1. 생산자가 생산하려고 할 때 더 이상 저장할 공간이 없는 문제가 발생할 수 있고,
  2. 이 공간에 소비자가 더 이상 소비할 아이템이 없는 경우가 발생할 수 있다.

Memory Map

Memory Map은 열린 파일을 메모리에 맵핑시켜서 공유합니다. 파일은 시스템의 전역적인(모두 공유할 수 있는) 자원이므로 서로 다른 프로세스들끼리 데이터를 공유할 수 있습니다.

psi1104 commented 3 years ago

IPC가 무엇인가요? 공유 메모리 방식은 어떤 문제점이 생길 수 있나요? 어떻게 해결할 수 있나요?