티스토리 뷰

Study/OS

[Process] Inter Process Communication (IPC)

생각많은 소심남 2013. 6. 21. 10:23

몇차례 걸쳐서 Process에 대한 내용을 다루고 있다. 실제로 우리가 쓰고 있는 OS상에서도 수많은 Process들이 상주해있으면서 user의 요구를 수행하고 있다. 그런데 우리가 돌리는 프로그램이 하나의 Process만이 수행하는 것은 절대 아니다. 상황에 따라서는 Process끼리 협력을 해서 수행하는 케이스도 발생한다. 예를 들어 지금 이렇게 글을 쓰는 과정도 network 과 관련한 Process와 Keyboard I/O와 관련한 Process가 동시에 수행되고 있기 때문에 온라인상으로 글을 올릴 수 있는 것이다. 보통 이럴 경우에는 system Resource를 같이 사용함으로써 효율적으로 처리할 수 있다. 이런 과정들을 뭉뚱그려서 Interprocess Communication (IPC)이라고 한다. 즉, 내부 Process끼리 대화를 하는 것이다. 어쩌면 위에서 예를 든 것처럼 자원을 공유해서 쓰는 케이스도 있을 것이고, 또는 각자가 독립적으로 처리하는 케이스도 존재할 것이다. 

 이 IPC의 모델은 크게 두가지가 있는데 하나는 Message Passing 방식이고 다른 하나는 Shared Memory 방식이다. 이번 포스트에서는 아마 이 두가지 방식의 차이에 대해서 조금 다뤄보려고 한다. 사실 지금 연구실에서 다루고 있고, 저번에도 한번 소개한 적이 있는 Intel Single-chip Cloud Computer (SCC)에는 이 Message Passing 방식의 Buffer와 Shared Memory 방식의 Buffer가 공존하고 있다. 그래서 이 원리를 조금 살펴보려고 다시 정리하고 있다.

 우선 위 두 모델은 앞에서 소개했던 Process간의 협력을 목적으로 형성되었는데 큰 차이는 서로 다른 Process가 같은 Information을 어떻게 전달하느냐에 대한 것이다. 


여기선 전자의 방식이 Message Passing 방식이고 후자가 Shared Memory 방식이다. 지금 다루고 있는 IPC의 큰 목적은 각 Process내에서 생성된 데이터들을 전달하는 것인데 MP 방식은 기존에 형성되어 있던 kernel을 거쳐서 Message를 전달하는 방식이다. OS내부 구조를 배운 사람이라면 이 방식이 User Level과 Kernel Level을 넘나드는 작업이라고 생각할 수 있겠다. 당연히 어딘가를 한번 거쳐서 전달되는 것이기도 하고 기존에 있던 Kernel을 활용하는 것이기에 쉽게 구현할 수 있다는 장점을 가지고, 같은 파일을 전달하는데 있어서 conflict가 발생하지 않는다. 하지만 이 점은 단점으로도 작용할 수 있다. 무언가를 거치기 때문에 당연히 kernel의 한 구석에는 이를 저장하기 위한 공간이 필요할 것이며, 속도도 직접 전달하는 방식에 비해서 느릴 것이다. 또한 앞에서 소개한 것처럼 level의 차이로 인해서 매번 system call이 호출되고 이로 인한 overhead도 발생하게 된다.

 반면 shared Memory방식은 인접한 process사이에 shared된 공간이 존재하기 때문에 system call을 부를 필요가 없어 kernel 에 대한 의존성이 낮다. 그만큼 속도도 빠르고 communication에 대한 편의도 가져올 수 있다. 다만 위의 그림에서도 볼 수 있듯이 생성공간에 대한 제한이 존재한다.

(2018/4/23 수정 : 공간을 공유하기 위해서 당연히 두 Process가 인접해야 한다는 점은 아닌것으로 확인됩니다. 잘못된 정보 전달드려 죄송합니다.) 

 Process도 처리되기 위해서는 정보가 필요하다. 그런데 이 정보에 대해서 언급하자면 정보를 만든 Producer가 있을 것이고, 그 정보를 소비할 consumer가 있을 것이다. 그 상태에서 이 Producer process와 consumer Process가 생산과 소비를  반복하면서 어느 순간에는 아무것도 없는 상태에서 Consumer가 소비하려고 시도하려는 경우가 발생할 것이다. 물론 원하는 데이터가 shared memory상에 없으니  그 consumer Process는 정상적으로 동작하지 못할 것이다. 또는 shared memory 상에 꽉 차있는 상태에서 Producer가 또 생산해내려 한다면 그 것도 역시 문제를 야기할 것이다. 이런 문제를 보통 Producer-Consumer Problem 이라고 한다. 이같은 문제는 shared memory상에 저장할 수 있는 데이터 영역이 한정되어있는 경우, 즉 bounded Buffer일 때 발생하는 문제이다. 그렇기 때문에 이런 문제를 해결하기 위해서는 Producer와 Consumer간의 동기화가 이뤄져야 한다. 앞의 예를 가져오면 Buffer가 꽉차있는 경우에는 Producer의 동작을 멈추게 한다던가, buffer가 비어있을 때는 consumer의 동작을 멈추게 한다던지 말이다. 그럴려면 Buffer의 상태를 지속적으로 확인해야 되는데 이런 방법을 Monitoring이라고 한다. 이 밖에도 semaphore나 mutex와 같은 Critical Section을 지정하는 방식으로 강제로 동기화하는 방법이 있을 수 있는데 이 부분은 추후에 더 정리해보고자 한다. 

 한편 Message Passing 방식에서도 IPC간에 문제가 발생할 수 있다. 아무래도 어딘가를 거쳐서 전달하다보니, 전달할 내용이 도착하기전에 또 보내라는 신호를 보낸다면 문제가 생길 것이다. 이 때는 동기적으로 처리할 것이냐 비동기식으로 처리하느냐에 따라서 다를 수 있다. 보통 동기식으로 처리하는 것을 Blocking이라고 하는데 말그대로 받은 결과가 올때까지 나머지 접근에 대해서 Block을 한다는 것이다. Message Passing에서는 Send()와 Recv() 를 통해서 메세지를 주고 받는데 보통 Blocking Send나 Blocking recv를 수행하면 원하는 작업을 수행할 때까지 나머지에 대한 Block을 거는 것이고, 반면 Non-blocking방식이라면 막지않고 오는대로 그대로 반응한다는 것이다. 

 뭐 아무튼 이렇게 Process간의 communication 내에서 어떤식으로 데이터를 주고받고 이에 따른 문제점에 대해서 조금 살펴보았다.

'Study > OS' 카테고리의 다른 글

[Memory] Memory Consideration in OS  (0) 2013.11.26
[OS] Context Switch  (0) 2013.06.29
[OS] POSIX Thread  (0) 2013.06.25
[Process] Process Creation  (0) 2013.06.20
[Memory] Memory Addressing  (2) 2013.06.20
[Process] Process Scheduling  (1) 2013.06.20
[Process] Process / Process Control Block  (2) 2013.06.19
댓글