생산자-소비자 문제
생산자-소비자 문제(producer-consumer problem)[1][2]는 여러 개의 프로세스를 어떻게 동기화할 것인가에 관한 고전적인 문제이다. 한정 버퍼 문제(bounded-buffer problem)라고도 한다.
유한한 개수의 물건(데이터)을 임시로 보관하는 보관함(버퍼)에 여러 명의 생산자들과 소비자들이 접근한다. 생산자는 물건이 하나 만들어지면 그 공간에 저장한다. 이때 저장할 공간이 없는 문제가 발생할 수 있다. 소비자는 물건이 필요할 때 보관함에서 물건을 하나 가져온다. 이 때는 소비할 물건이 없는 문제가 발생할 수 있다.
문제 해결
편집이 문제를 해결하는 것을 생산자-소비자 협동이라 하며, 버퍼가 동기화되어 정상적으로 동작하는 상태를 뜻한다. 문제를 해결하기 위해 세마포어를 활용할 수 있다.
불완전한 방법
편집- 변수
- Empty : 버퍼 내에 저장할 공간이 있는지를 나타낸다. (초기값은 n)
- Full : 버퍼 내에 소비할 아이템이 있는지를 나타낸다. (초기값은 0)
- Mutex : 버퍼에 대한 접근을 통제한다. (초기값은 1)
- 프로세스
- 생산자 프로세스
do {
...
아이템을 생산한다.
...
wait(empty); //버퍼에 빈 공간이 생길 때까지 기다린다.
wait(mutex); //임계 구역에 진입할 수 있을 때까지 기다린다.
...
아이템을 버퍼에 추가한다.
...
signal(mutex); //임계 구역을 빠져나왔다고 알려준다.
signal(full); //버퍼에 아이템이 있다고 알려준다.
} while (1);
- 소비자 프로세스
do {
wait(full); //버퍼에 아이템이 생길 때까지 기다린다.
wait(mutex);
...
버퍼로부터 아이템을 가져온다.
...
signal(mutex);
signal(empty); //버퍼에 빈 공간이 생겼다고 알려준다.
...
아이템을 소비한다.
...
} while (1);
모니터를 이용한 방법
편집monitor ProducerConsumer
{
int itemCount = 0;
condition full;
condition empty;
procedure add(item)
{
if (itemCount == BUFFER_SIZE)
{
wait(full);
}
putItemIntoBuffer(item);
itemCount = itemCount + 1;
if (itemCount == 1)
{
notify(empty);
}
}
procedure remove()
{
if (itemCount == 0)
{
wait(empty);
}
item = removeItemFromBuffer();
itemCount = itemCount - 1;
if (itemCount == BUFFER_SIZE - 1)
{
notify(full);
}
return item;
}
}
procedure producer()
{
while (true)
{
item = produceItem();
ProducerConsumer.add(item);
}
}
procedure consumer()
{
while (true)
{
item = ProducerConsumer.remove();
consumeItem(item);
}
}
같이 보기
편집각주
편집- ↑ Arpaci-Dusseau, Remzi H.; Arpaci-Dusseau, Andrea C. (2014), 《Operating Systems: Three Easy Pieces [Chapter: Condition Variables]》 (PDF), Arpaci-Dusseau Books
- ↑ Arpaci-Dusseau, Remzi H.; Arpaci-Dusseau, Andrea C. (2014), 《Operating Systems: Three Easy Pieces [Chapter: Semaphores]》 (PDF), Arpaci-Dusseau Books