📌 IPC (Interprocess Communication)
프로세스의 가장 큰 특징은 독립된 메모리 공간을 할당 받는다는 것이다. 이는 개별 독립적이기 때문에 동기화를 위한 작업을 하지 않아도 된다는 장점이 있으나, 자원 소모적이라는 단점도 함께 존재한다.
그렇다면 이렇게 독립적으로 메모리 공간을 할당 받는 프로세스들이 어떻게 상호 간 통신을 할까?
이는 바로 커널에서 제공하는 IPC를 통해 서로 다른 프로세스들끼리 통신을 한다. IPC (=Interprocess Communication)는 프로세스들 사이에 서로 데이터를 주고 받는 행위 또는 그에 대한 방법이나 경로를 말한다. (IPC 정의 출처: 위키피디아)
- IPC 없이는 프로세스 간 통신이 어렵기 때문에 커널에서 IPC라는 내부 프로세스 간 통신 기능을 제공한다. 커널에 대한 정의는 다음과 같다.
- 커널: 메모리에 상주하는 부분으로, 운영체제의 핵심적인 부분을 말함.
그리고 이러한 IPC 통신 기법은 크게 두 가지로 분류되는데, 하나는 Shared memory(공유 메모리) 이고, 다른 하나는 Message passing(메시지 전달) 이다. 이제 아래에서 두 개의 통신 기법에 대해 설명하려고 한다.
📌 공유 메모리 (Shared memory)

공유 메모리 (Shared memory): 프로세스 간 공유된 메모리를 생성하여 이용하는 것을 말함
스레드들은 하나의 프로세스에서 공유된 자원으로 데이터를 공유하며 동작한다. 이와 비슷하게 공유 메모리를 이용한 프로세스들은 공유 메모리를 우선 생성하여 해당 메모리에서 데이터를 공유하며 통신한다. 프로세스들은 이러한 공유 메모리에서 read/write 형식으로 동작한다.
프로세스가 공유 메모리를 생성하여 동작하기까지의 작동 과정은 다음과 같다.
- 프로세스가 커널에게 공유 메모리 할당을 요청한다.
- 커널은 해당 프로세스에 메모리 공간을 할당한다 (= 공유 메모리).
- 공유 메모리가 설정되면 그 이후에는 커널의 관여 없이 통신이 가능해진다. 즉, 공유 메모리를 통해 프로세스가 통신을 하는 것이다.
이러한 공유 메모리를 활용한 프로세스 간 통신 기법의 가장 큰 장점은 커널의 관여 없이 통신하므로 IPC 통신 속도가 상대적으로 빠르다는 것이다. 커널은 프로세스 간 통신을 위해 메모리 공간을 할당해주기만 할 뿐, 프로세스가 공유 메모리를 통해 통신을 할 때 직접적으로 관여하지 않는다. 그렇기 때문에 커널을 거치지 않고 통신하므로 IPC 통신 속도가 빠르다는 장점이 있다.
하지만 커널을 거치지 않는다는 장점과 함께 단점 또한 존재한다. 이는 바로 커널의 개입이 없기 때문에 커널이 제공하는 동기화 작업을 받지 못한다는 것이며, 그렇기 때문에 프로세스의 동시적인 접근을 직접 제어해야 한다는 단점이 있다.
- 동기화의 정의는 다음과 같다.
- 동기화(Synchronization): 여러 프로세스 혹은 스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것.
공유 메모리의 단점을 간단하게 이해하자면 다음과 같다. 만약 process 1과 process 2가 존재할 때, process 1이 공유 메모리에 데이터를 전달했다 하더라도 process 1이 언제 데이터를 전달했는지 process 2가 알 수 없다는 것이다. 그렇기 때문에 개별적으로 동기화 작업이 필요하다.
📌 메시지 전달 (Message passing)

메시지 전달 (Message passing): 프로세스들이 커널을 통해 메시지를 전달하는 방식
지겹도록 말하지만 프로세스들은 서로 직접적인 통신이 힘들다. 그렇기 때문에 이전과 같이 공유 메모리를 생성하여 프로세스들이 공유 메모리를 통해 통신하는 기법이 존재한다. 하지만 공유 메모리는 장점이자 단점인 '커널이 직접 개입하지 않고, 프로세스들은 커널을 경유 하지 않는다' 는 특징을 지니고 있는데, 이와 다르게 메시지 전달은 커널을 경유하여 메시지를 전달하는 방식을 말한다. 프로세스가 커널에게 데이터를 보내면 (=send), 다른 프로세스는 커널에게 해당 데이터를 받는다 (=receive). 즉, 공유 메모리는 프로세스들이 read/write를 하며 통신을 하였으나, 메시지 전달은 프로세스들이 커널을 경유하여 send/receive를 하며 통신을 한다.
그러면 우리는 공유 메모리의 장·단점의 반대가 메시지 전달의 장·단점이라는 것을 알 수 있다. 메시지 전달 방식은 프로세스가 데이터를 주고 받을 때 커널에서 제어해주기 때문에 별도의 동기화가 필요 없다는 장점을 지니고 있다.
- 더 정확히 말하자면, 커널은 send, receive 연산에 대해 동기화를 제공한다.
이와 반대로 메시지 전달은 커널을 경유하기 때문에 속도가 상대적으로 느리다는 단점을 지니고 있다.
메시지 전달의 예시는 파이프 (pipe), 메시지 큐 (message queue), 소켓 (socket) 등이 있다.
📌 메시지 전달 예시 1. 파이프 (Pipe)

파이프 (Pipe): 서로 다른 두 개의 프로세스를 연결해 하나의 프로세스는 쓰기만, 다른 하나의 프로세스는 읽기만 하는 방식
파이프는 바로 위의 정의와 같이 쓰기만 하는 프로세스와 읽기만 하는 프로세스 두 개로 이루어져 있다. 그래서 파이프는 부모-자식 간의 단방향 통신이라는 특징을 갖고 있다. 또한 한쪽 방향으로만 통신이 가능하기 때문에 반이중 통신이라고도 한다.
파이프의 정의에서 볼 수 있듯, 파이프의 하나의 프로세스는 읽기만 하고 다른 하나의 프로세스는 쓰기만 하는 단순한 데이터 흐름에 적합하다는 장점을 갖고 있다.
물론 이러한 단방향적인 파이프를 양방향으로 만들 수 있는 방법이 있다. 이는 간단하게 생각할 수 있는데, 이는 바로 다른 방향으로 읽고 쓸 수 있도록 파이프를 하나 더 만드는 것이다. 하지만 이렇게 양방향으로 통신이 가능하도록 파이프를 하나 더 만들 경우 구현이 복잡해질 뿐만 아니라 낭비 또한 심하다는 단점을 갖고 있다.
📌 메시지 전달 예시 2. 메시지 큐 (Message queue)

메시지 큐 (Message queue): 큐를 활용한 방식으로, FIFO(First In First Out)를 통해 메시지를 송수신하는 기법
메시지 큐는 파이프와 달리 양방향 통신이며, 부모-자식 간의 프로세스가 아니더라도 프로세스 간 메시지 송·수신이 가능하다는 특징을 지니고 있다.
메시지 큐는 비동기(Asynchronous) 방식이므로 큐에 넣어둔 뒤 나중에 처리할 수 있다는 장점을 지니고 있다. 비동기 외에도 비동조, 탄력성, 과잉, 보증, 확장성의 장점 또한 지니고 있다. 이에 대한 간단한 설명은 다음과 같다.
- 비동조: 어플리케이션과 분리
- 탄력성: 일부가 실패 시 전체에 영향을 받지 않음
- 과잉: 실패할 경우 재실행이 가능
- 보증: 작업이 처리된 것을 확인 가능
- 확장성: 다수의 프로세스등리 큐에 메시지를 보낼 수 있음
메시지 큐의 단점은 메시지가 제대로 전달 되었는지 알 수 없다는 것이다. 그렇기 때문에 큐에 데이터를 넣고 나오는 과정에서 오버헤드가 발생할 수도 있다. 또한 데이터가 많이 쌓일수록 추가적인 메모리 자원이 필요하다는 단점 또한 지니고 있다.
📌 메시지 전달 예시 3. 소켓 (Socket)
소켓은 네트워크 통신을 위한 기술로, 서로 다른 노드 (=컴퓨터) 간 네트워크 통신을 위한 기술이다. 하지만 여기서 말하는 IPC Socket은 같은 컴퓨터 내에 서로 다른 프로세스 간 통신을 말하며, 이를 Unix Domain Socket이라고도 한다.
- 소켓: 네트워크 소켓은 컴퓨터 네트워크를 경유하는 프로세스 간 통신의 종착점(출처: 위키피디아)
- 소켓은 크게 두 가지로 나뉜다.
- AF_UNIX: 유닉스 도메인 소켓 (같은 호스트 내 프로세스 간 통신)
- AF_INET: 인터넷 소켓 (인터넷을 통해 다른 호스트와 통신)

- 위의 사진에서의 메서드는 다음을 의미한다.
- socket(): 소켓을 생성
- connect(): 통신 요청
- send() / recv(): 통신
- close(): 소켓 종료
- bind(): 주소 할당
- listen(): 통신 요청을 기다림
- accept(): 통신 수락
우선 Server Socket()은 bind(), listen(), accept()를 하며 Client Socket과의 연결을 위한 준비를 한다.
그리고 Client Socket은 connect()를 통해 Server Socket에 통신을 요청하고, Server Socket이 accept()를 통해 통신을 수락할 경우 send()/recv()를 통해 서로 데이터를 주고 받는다.
마지막으로 연결이 끝날 경우 close()를 통해 소켓을 종료한다.
소켓 (Unix Domain Socket)을 활용할 경우 위에서 보았듯 서버/클라이언트 환경을 구축하는데 용이하다는 장점을 지니고 있다. 또한 원격에서 프로세스 간 데이터를 공유할 때 사용할 수 있다는 장점을 갖고 있으며 메시지 큐와 같이 양방향 통신이 가능하다는 장점을 지니고 있다.
하지만 Internet UDP와 달리 경로를 지정할 수 없다는 단점을 지니고 있다.
👀 Reference
'Computer Science > Operating System' 카테고리의 다른 글
동기화 (Synchronization)문제와 해결 방안 (0) | 2023.03.06 |
---|---|
멀티 프로세스(Multi Process) & 멀티 스레드(Multi Thread) (0) | 2023.03.06 |