728x90
은행동기화 문제 같이 우리 실생활에서 사용되는 문제들도 있지만 예전부터 전통적으로 문제가 되는 문제들이 있다. 이를 전통적 동기화 문제라고 한다.
Producer and Consumer Problem
- 생산자 소비자 문제
- 생산자는 데이터를 생성하고 소비자는 그 데이터를 소비한다. 예를들어 컴파일러가 데이터를 컴파일하면 어샘블리 코드가 되고 어셈블리어를 번역하여 기계어가 된다.
- 생산자는 데이터를 생성하고서 바로 소비자에게 넘기지 않는다. I/O차이, 연산차이 등 속도를 맞추기 위해 먼저 buffer에 데이터를 삽입하고 이후 소비자가 버퍼에 접근해 take 하는 식으로 처리된다. 즉, 버퍼는 생산자와 소비자가 모두 접근하는 Critical Section이 되는 것이다.
- 이를 해결하기 위해 상호배재를 위한 세마포어를 한개 사용한다.
- 그렇지 않으면 코드가 실행되지 않거나, 버퍼에 데이터가 없는데 taken하게되는 오류가 발생할 확률이 매우 높다.
- 이를 해결하기 위해 상호배재를 위한 세마포어를 한개 사용한다.
/****** 생산자 ******/
class Producer extends Thread {
Buffer b;
int N;
Producer(Buffer b, int N) {
this.b = b; this.N = N;
}
public void run() {
for (int i=0; i<N; i++)
b.insert(i);
}
}
/****** 소비자 ******/
class Consumer extends Thread {
Buffer b;
int N;
Consumer(Buffer b, int N) {
this.b = b; this.N = N;
}
public void run() {
int item;
for (int i=0; i<N; i++)
item = b.remove();
}
}
void insert(int item) {
/* check if buf is full */
while (count == size)
;
/* buf is not full */
buf[in] = item;
in = (in+1)%size;
count++;
}
int remove() {
/* check if buf is empty */
while (count == 0)
;
/* buf is not empty */
int item = buf[out];
out = (out+1)%size;
count--;
return item;
}
}
Busy Wait
- 뮤텍스를 위해 세마포어를 사용하면 상호배재를 해결할 수 있지만 한가지 문제가 있다. 생산자는 삽입을 해야하는데 버퍼가 꽉 찼을 경우, 소비자는 사용해야하는데 버퍼가 비었을 경우, 계속 반복을 돌며 비었는지 안비었는지 확인하고 있다. 이것을 쉬고 있는데도 바쁘다는 의미로 busy wait이라 부른다.
- 이것은 심각한 cpu낭비를 초래한다. 그러므로 두개의 세마포어를 추가한다. 이번 세마포어는 block을 위한 세마포어이다.
[생산자]
empty.acquire();
PRODUCE;
full.release();
[소비자]
full.acquire();
CONSUME;
empty.release();
- 이렇게 하면 CPU를 효율적으로 사용하면서 상호배타적인 문제도 해결할 수 있다.
'CS > 운영체제(OS)' 카테고리의 다른 글
DeadLock (교착상태) (0) | 2023.12.11 |
---|---|
OS - 식사하는 철학자 문제와 교착상태(DeadLock) (0) | 2023.11.27 |
OS - 임계구역과 세마포어 (1) | 2023.11.20 |
OS - 프로세스 동기화 개념 (0) | 2023.11.11 |
OS - CPU 스케줄링(3), 프로세스의 생성과 소멸, 쓰레드 (0) | 2023.11.07 |