전공공부/운영체제 (Operating System)

[운영체제] Processes (3) - Interprocess Communication (IPC)

jooona 2020. 12. 17. 18:03
반응형

Process 파트의 마지막 내용으로 Interprocess Communication, 즉 process 간 통신에 대해 알아보겠습니다. Process들은 운영체제 내에서 병렬적으로 수행되기 때문에 서로 독립적이면서도 상호 협력적인 관계에 있습니다. 이러한 Process들 간의 협력을 통해 우리는 몇 가지 이득을 취할 수 있습니다. 

 

1. 정보 공유 (Information Sharing): 여러 응용 프로그램들이 동일한 정보에 흥미를 가질 수 있기 때문에 병행적으로 접근이 가능한 것이 좋다.

2. 계산 가속화 (Computation Speedup): 작업을 빨리 끝마치기 위해서는 작업을 서브 작업들로 분할하여 여러 process들에서 병렬적으로 수행하는 것이 좋다.

3. 모듈성 (Modularity): 시스템의 기능들을 프로세스들로 나누어 모듈화하여 시스템을 구성할 수 있다.

 

하지만 어쨋든 IPC에 대해서 한 문장으로 말하자면 IPC는 'Process들 간에 데이터와 정보를 교환할 수 있게 해 준다.'라고 할 수 있습니다.

 

IPC는 대표적으로 두 가지 방법을 통해 실행됩니다.

 

1. Shared Memory

두 가지 방법 중 첫번째는 Shared Memory라는 방법입니다. Shared Memory는 쉽게 말해서 메모리에 서로 공유하고 있는 영역이 있어서 그 부분에 자신이 원하는 데이터를 작성하는 방법입니다. 물론 그 공유하는 영역을 만드는 작업은 운영체제의 도움을 받아야 가능합니다. Process들은 단순히 메모리에 데이터를 읽고 쓸 수 있으며, 어떤 업데이트가 일어나더라도 곧바로 모든 process들이 그 내용을 확인할 수 있습니다.

 

그리고 가장 중요한 장점은 일단 공유 메모리 영역을 만들어 놓기만 하면, 그 뒤에는 Kernel의 어떤 도움도 필요로 하지 않는다는 것입니다. 앞에서도 여러 번 언급했듯이, Kernel을 자주 이용한다는 것은 System call이 자주 호출된다는 것을 뜻하고, 이는 성능적으로 큰 overhead를 야기합니다. 따라서 shared memory는 성능적으로는 다른 한 가지 방법인 Message Passing에 비해 굉장히 큰 장점이 있습니다.

 

Shared Memory의 기본 개념

Shared memory 방식을 사용하기 위해 우선 process들은 자신의 주소 공간에 공유 공간으로 사용할 부분을 준비합니다. 그리고 이 shared memory를 이용해 통신하고자 하는 다른 process들은 이 세그먼트를 자신의 주소 공간에 추가하여야 합니다. 일반적으로 운영체제는 한 process가 다른 process의 memory에 접근하는 것을 금지하기 때문에 Kernel의 도움을 받아서 이 제약 조건을 제거하는 과정이 필요합니다. 이런 과정을 거친 뒤에 process들은 공유 영역에 메세지를 읽고 쓸 수 있습니다.

Shared Memory 구조

하지만 이 shared memory 방법에서는 동기화가 중요한 이슈로 떠오르게 됩니다. 이 동기화에 대해서는 뒤에서 더 자세하게 알아보겠습니다. 

 

2. Message Passing

Message Passing 방법은 데이터를 메세지 처럼 전달하는 방법입니다. Message passing은 메세지를 보내는 send와 메세지를 받는 receive 두 가지 연산으로 실행됩니다. 그리고 어떤 방식으로 메세지를 주고받는지에 따라 또 두 가지 방법으로 분류할 수 있습니다. 

 

Message Passing의 기본 개념

 

1. Direct Communication

 

Direct Commnuication은 말 그대로 point-to-point로 직접 전달하는 방식입니다. send 연산은 send(수신자 PID, message)로, receive 연산은 receive(송신자 PID, message)의 형태로 구성됩니다. 통신을 위해 상대의 ID만 알고 있다면 두 process 간에 자동으로 연결이 구축됩니다. 연산 자체에 수신자 혹은 송신자의 ID를 적어줘야 하기 때문에 혹시 ID가 수정되게 되면 아예 코드 전체를 수정해줘야 하는 단점이 있습니다. 또한 1대 1 통신만 가능하고 Broadcast 기능은 사용할 수 없다는 것도 한 단점입니다.

 

2. Indirect Communication

 

Indirect Communication은 직접 메세지를 전달하지 않고 mailbox를 이용하는 형태입니다. 다시 말해서, 수신자는 mailbox에 원하는 메세지를 담고, 송신자는 mailbox에서 원하는 메세지를 가져가는 형식입니다. 어떤 process라도 mailbox에 정보를 넣을 수 있고 빼 갈 수 있습니다. 연산은 send(mailbox 이름, message), receive(mailbox 이름, message)의 형태를 가집니다.

 

Indirection Communication

Message Passing 방법에서는 Blocking과 Nonblocking 방식을 통해 메세지를 주고받습니다.

 

1. Blocking Send: 송신하는 process는 메세지가 수신자에 의해 수신될 때까지 아무것도 하지 못하고 blocking 된다.

2. Nonblocking Send: 송신하는 process가 메세지를 보내고 그 수신의 여부와 관계없이 다음 작업을 수행한다.

3. Blocking Receive: 수신하는 process는 메세지가 이용 가능할 때까지 아무것도 하지 못하고 blocking 된다.

4. Nonblocking Receive: 수신하는 process는 유효한 메세지인지 Null인지 계속 검색한다.

 

3. Pipes

두 process 간의 교류가 꼭 쌍방향일 필요는 없습니다. 상황에 따라서는 생산자와 소비자의 관계로 한 process는 보내기만 하고 한 process는 받기만 하는 경우가 생길 수도 있습니다. 이러한 상황에서는 pipe를 유용하게 사용할 수 있습니다. pipe() system call을 통해 pipe를 생성하면 pipe의 한쪽 끝은 (pipe [0]) 읽기를 담당하고 나머지 한쪽 끝은 (pipe [1]) 쓰기를 담당합니다. 그리고 pipe는 오로지 자신을 생성한 process로부터만 접근이 가능합니다. 하지만 부모 process가 자식 process를 생성할 때 pipe에 관한 정보도 상속하기 때문에 부모 process가 생성한 pipe로 자식 process와 소통하는 것은 가능합니다. (pipe()를 먼저 호출한 뒤 fork()를 호출하면 부모와 자식 간에 소통이 가능합니다.)

 

특별한 케이스로 Named pipe라는 것이 존재합니다. FIFO라고도 불리며 pipe임에도 불구하고 양방향 통신이 가능합니다. 또한 꼭 부모-자식 관계일 필요도 없으며 일단 생성되면 같은 하드웨어 안에 있는 여러 process가 사용할 수도 있습니다. 게다가 생성한 process가 죽는다고 해서 이 pipe가 사라지지도 않습니다. mkfifo() system call을 이용해서 named pipe를 만들 수 있으며, open(), read(), write(), close()와 같은 system call을 이용해 제어할 수 있습니다. 

 

4. Client-Server System

두 process들이 네트워크를 이용해 통신을 하는 방법으로 소켓을 사용할 수 있습니다. 소켓들은 IP 주소와 Port Number를 통해 서로를 구별하며 일반적으로 서버-클라이언트의 구조를 가집니다. 소켓에 대해서는 정말 설명할 것이 많지만 운영체제에서는 크게 다루지 않습니다.

 

Socket을 이용한 방법 외에도 Remote Procedure Calls (RPC)라는 방법도 있습니다. 한국말로는 '원격 프로시져 호출'이라고 불리는데 함수 호출을 네트워크를 이용해 할 수 있는 방법을 뜻합니다. 즉, RPC 서버에 함수가 실제로 구현이 되어있고 클라이언트의 코드에서 함수를 호출하면 서버에 있는 함수가 실행되는 형태를 띱니다. 서버와 클라이언트 간에는 Stub라는 것을 이용해 서로 네트워크를 연결합니다. 그냥 이런 것도 있다 하는 정도로만 짚고 넘어가면 될 것 같습니다.

 

 

 

 

 

Process에 대해 3번에 나누어 정리를 해보았습니다. Process는 뒤에서 공부하게 될 Thread나 동기화, 스케쥴링 등에도 기본적으로 항상 사용되는 개념이기 때문에 확실하게 이해를 하고 넘어가는 것이 좋다고 생각합니다. 다음 글부터는 Thread에 대해 공부해보도록 하겠습니다. 읽어주셔서 감사합니다.

반응형