미래와 연결될 첫걸음

Interprocess Communication(IPC) #3.4 Shared Memory 본문

Infra/OS

Interprocess Communication(IPC) #3.4 Shared Memory

Traveler:) 2019. 6. 29. 23:50

먼저, Shared Memory system에 대해 자세히 살펴보는 시간을 갖도록 하겠습니다.

 

● Shared Memory

 

Shared-Memory는 Shared memory공간이 따로 존재해서 그 공간에서 Communication이 이루어진다고 했죠?

이 공간에서 어떠한 일이 일어나는지 살펴보겠습니다.

우선, 이 공간이 생기기 위해서는 process A 와 process B가 있을 때(혹은 두 개 이상), process A, B 둘 다 shared memory를 사용하겠다는 동의가 있어야합니다. 즉, 일방적으로 어떤 process 한쪽에서 공유하고 싶다고 해서 shared memory 공간이 주어지는게 아니라는 이야기죠. 양측 동의가 다 있을 때, shared memory 공간이 주어지게 됩니다. 

Shared memory 공간이 주어지게 되면, 더 이상 OS의 도움을 받지 않습니다. 받을 필요가 없는 거죠. Shared memory 안에서 알아서 정보들을 주고 받으면 되니까요.

 

그러나, 한가지 지켜져야 할 것이 있습니다. 

이 shared memory 공간에 writing을 할 때에는 공유하는 processes가 동시에 writing(수정)할 수 없습니다.

왜 이렇게 해야하는지 고민해보면 꽤나 간단한데요, Process A, B 그리고 C 가 있다고 생각합시다. Process A와 B가 shared memory에서 동시에 writing을 한다고 하고, Process A가 먼저 writing을 끝냈다고 칩시다. 그러면 Process C는 shared memory에서 이 수정된 정보를 가지고 가려는데, 그 순간 Process B가 writing이 끝나서 그 정보가 바뀌어 버렸어요. 그러면 Process C는 계속 바껴버리는 정보를 사용하기 힘들겠죠. 즉, 동기화가 되어야 한다는 이야기입니다.

 

Shared-Memory system에 대한 적용을 위한 개념으로 Producer - Consumer 문제가 있습니다.

     Producer는 Consumer가 사용할 정보를 생산하는 역활을 합니다. 

            ex) 컴파일러(Producer)는 어셈블러(Consumer)가 사용할 어셈블리 언어가 생산하죠.

                  Server(Producer) - Client(Consumer) 이렇게 나타낼 수도 있겠죠?

 

이렇게 Producer - Consumer 문제를 적용하기 위해 필요한 것이 바로 Shared memory입니다. Producer와 Consumer는 동시에 실행되야 하구요, Producer는 buffer에 items을 제공하고, Consumer는 사용해야하죠. Buffer가 shared memory 공간이라고 하면, 

딱 Shared-Memory system이 되겠네요.

이 buffer에도 개념적으로 두가지가 있는데요,

    - unbounded buffer(버퍼의 사이즈 제한없음) : unbounded buffer는 consumer는 계속 새로운 item이 생산되기까지 기다려야하구요, producer는 항상 item을 생산할 수 있습니다.(제한이 없으니까요),

    - bounded buffer(제한있음) : bounded buffer는 consumer는 buffer가 비어있을 때 기다리구요, producer는 buffer 가득 차 있으면, 기다립니다.

 

bounded buffer producer를 코드로 한번 살펴보겠습니다.(실제적인 것은 아니고 코드로 풀어놓은 것입니다; pseudo code)

 

#define BUFFER_SIZE 10

typedef struct { ... }item;

item buffer[BUFFER_SIZE]; // shared memory 공간이고, 순환 배열로 사용됩니다
int in = 0; // item이 들어오는 것입니다(Producer)
int out =0; // item이 나가는 것이겠죠(Consumer)

//---------------------- Producer -----------------------
while(true){
    /* next_producerd에서 item이 생산됩니다.*/
     while ( ( in + 1 ) % BUFFER_SIZE == out ); //buffer가 가득 차서 아무것도 하지 않습니다.

     buffer[in] = next_producerd;
     in = ( in +1 ) % BUFFER_SIZE; 
}
//---------------------- Consumer -----------------------
while (true) {
    /* next_consumered에서 item이 소비됩니다*/
     while( in == out ); //buffer가 비어 있어서 아무것도 하지 않습니다.

     next_consumered = buffer[out];
     out = (out + 1) % BUFFER_SIZE;
}