운영체제 - 병행제어(7)
2020-10-06
OS를 공부하면서 정리를 한 내용들 입니다.
동기화 문제 해결을 위해 세마포 이외의 모니터 방식에 대해 알아봅니다.
지난 번까지는 3가지 전통적인 문제에 대해 세마포어를 이용해서 동기화 문제를 해결하는 방식을 포스팅했습니다.
그러나 세마포어에서도 문제점이 몇 가지 있습니다.
세마포어의 문제점
- 코딩하기 힘들다.
- 정확성(correctness)의 입증이 어렵다.
- 자발적 협력(voluntary cooperation)이 필요하다.
- 한번의 실수가 모든 시스템에 치명적 영향을 입힌다.
이러한 점들로 인해서 등장하게된 것이 Monitor
라는 것입니다.
Monitor
동시 수행중인 프로세스 사이에서 abstract data type의 안전한 공유를 보장하기 위한
high-level(프로그래밍 언어) synchronization construct 입니다.
-
모니터 내에서는 한번에 하나의 프로세스만이 활동이 가능합니다.
-
프로그래머가 동기화 제약 조건을 명시적으로 코딩할 필요가 없습니다.
-
프로세스가 모니터 안에서 기다릴 수 있도록 하기 위해
condition variable
을 사용합니다.
이때
condition variable
은 wait와 signal 연산에 의해서만 접근이 가능합니다.
x.wait()
x.wait()을 invoke한 프로세스는 다른 프로세스가 x.signal()을 invoke하기 전까지 suspend합니다.
x.signal()
x.signal()은 정확하게 하나의 suspend된 프로세스를 resume합니다.
Suspend된 프로세스가 없으면 아무 일도 일어나지 않습니다.
Bounded-Buffer Problem
monitor bounded_buffer
{
int buffer[N];
condition full, empty;
/* condition var.은 값을 가지지 않고 자신의 큐에 프로세스를 매달아서 sleep 시키거나
큐에서 프로세스를 깨우는 역할만 함 */
void produce(int x){
if there is no empty buffer
empty.wait();
add x to and empty buffer
full.signal();
}
void consume(int *x){
if there is no full buffer
full.wait();
remove an item from buffer and stroe it to *x
empty.signal();
}
}
Dining Philosophers Example
monitor dining_philosopher
{
enum{thinking, hungry, eating} state[5];
condition self[5];
void pickup(int i){
state[i]=hungry;
test(i);
if(state[i] != eating)
self[i].wait(); /* wait here*/
}
void putdown(int i){
state[i]=thinking;
/* test left and right neighbors*/
test((i+4)%5); /* if L is waiting*/
test((i+1)%5);
}
void test(int i){
if((state[(i+4)%5]!=eating)&&(state[i]==hungry)&&(state[(i+1)%5]!=eating)){
state[i]=eating;
self[i].signal(); /* wake up Process*/
}
}
void init(){
for(int i = 0 ; i < 5; i++)
state[i]=thinking;
}
}
Each Philosopher: {
pickup(i); // enter monitor
eat();
putdown(i);// enter monitor
think();
} while(1)
-참고 KOCW 이화여자 대학교 반효경 교수님 : 운영체제 강의