유한한 개수의 데이터를 보관하는 Buffer에 여러 명의 생산자들과 소비자들이 접근한다. 생산자의 경우 데이터를 생성하면 Buffer에 저장하는데 이 때 저장할 Buffer 공간이 없을 수 있는 문제가 발생 할 수 있다.
소비자의 경우 데이터가 필요 할 때 Buffer에서 데이터를 가져오는데 , 이 때 가져올 데이터가 Buffer에 없는 문제가 발생 할 수 있다.
해결방법은 생산자-소비자 협동으로 세마포어를 사용하여 버퍼를 동기화 시키는 것이다.
int n;
semaphore empty = n; // 버퍼 내에 저장할 공간이 있는지
semaphore full = 0 // 버퍼 내에 소비 할 데이터가 있는지
semaphore mutex = 1 // 버퍼에 대한 접근을 통제하여 동기화를 충족시켜주는 세마포어
while(true){
// Data 생산
wait(empty); // 버퍼에 빈 공간이 생길 때 까지 기다린다.
wait(mutex); // 임계 영역에 진입 하기 전까지 기다린다.
// 데이터를 버퍼에 추가
signal(mutex); // 임계 영역을 빠져나왔다고 알려준다.
signal(full); // 버퍼에 데이터가 있다고 알려준다.
}
while(true){
wait(full); // 버퍼에 데이터가 들어올 때 까지 기다린다.
wait(mutex); // 임계 영역에 진입 하기 전까지 기다린다.
// 버퍼로부터 데이터를 가져온다.
signal(mutex);
signal(empty); // 버퍼에 빈 공간이 생겼다고 알려준다.
}
여러 명의 독자(Readers)와 저자(Writers)들이 하나의 저장 공간 (Buffer) 을 공유하며 이를 접근 할 때 발생하는 문제이다.
이 때, 독자와 저자 사이의 기아문제가 발생 할 수 있다. ( 독자의 수가 압도적으로 많고, 저자는 계속해서 기다리는 상황이 발생 가능 vice versa)
해결 방법은 세마포어를 사용하는 것이다.
int readcount = 0 //현재 Buffer에 접근 중인 독자의 수
// 독자 수가 0 일 경우 저자가 임계 영역에 접근 가능
semaphore rw_mutex = 1 //저자와 독자 사이 동기화
semaphore mutex = 1 // 상호 배제를 보장하기 위해 사용
while(true){
wait(rw_mutex); // 임계 영역에 들어가기 위해 기다리는 중
// 쓰기 작업 수행
signal(rw_mutex); // 임계 영역에서 빠져나옴
}
while(true){
wait(mutex);
readcount++; // 독자수 1 증가
if(readcount = 1 )
wait(wrt) // 쓰고 있는 저자가 없을 때 까지 기다리기
signal(mutex);
// 읽기 작업 수행
wait(mutex);
readcount--; // 독자수 1 감소
if(readcount = 0)
signal(rw_mutex); // 독자가 없다면 알려줘서 기다리고 있는 독자/저자를 끼운다.
signal(mutex);
}
철학자들은 서로 대화 할 수 없으며, 양쪽에 있는 포크를 모두 쥐어야지 식사를 할 수 있다.
각 포크에 세마포어를 상호배제 세마포어를 걸어준다. 철학자가 포크를 집을 때, wait
연산을 하고, 포크를 내려놓을 때 signal
연산을 하는 것이다.
while(true){
// 포크 양쪽 가져오기
wait(포크[i]);
wait(포크[(i+1)%5]);
// 냠냠 먹는다.
// 포크 양쪽 놓기
signal(포크[i]);
signal(포크[(i+1)%5]);
// 철학적인 생각한다..
}
이렇게 구현 할 시, 상호배제는 충조갛지만 교착상태
와 기아현상
이 발생한다.
이 때 만약 이 때 모든 철학자들이 오른쪽에 놓여있는 포크를 집는다면 , 왼쪽의 포크는 이미 사라진 상태이기 때문에 모든 철학자들이 서로가 포크를 내려놓기를 무한정 대기하는 문제가 생긴다.
몇몇 철학자들만 양손 포크를 쥐어서 식사를 하는 경우가 발생 할 수 있다.
철학자들의 상태를 thinking
hungry
그리고 eating
으로 나눈다.
eating
상태가 아닐 때만 바꿀 수 있다.그럼에도 불구하고 기아현상은 발생 할 수 있다.