본문 바로가기

CS/운영체제

[운영체제] 6. Process Synchronization (4)

더보기

kocw 반효경 교수님의 운영체제 강의를 수강 후 작성한 글입니다.

1. Monitor

Semaphore의 문제점

- 코딩하기 힘들다.

- 정확성의 입증이 어렵다.

- 자발적 협력이 필요하다.

- 한번의 실수가 모든 시스템에 치명적 영향을 미친다.

 

예)

 

V(mutex);
critical section
P(mutex);

 

P, V 순서가 뒤바뀜 → Mutual exclusion이 깨지는 문제 발생

 

P(mutex);
critical section
P(mutex);

 

공유데이터를 반납하는 코드 없음 → Deadlock

 

Monitor

 

동시 수행중인 프로세스 사이에서 abstract data type의 안전한 공유를 보장하기 위한 high-level synchronization contruct. 모니터 내의 procedure를 통해서만 공유 데이터에 접근 가능하도록 함으로써 프로그래머가 따로 lock을 걸 필요없이 모니터가 동기화를 책임진다.

 

- 모니터 내에서는 한번에 하나의 프로세스만이 활동 가능 

- 프로그래머가 동기화 제약 조건을 명시적으로 코딩할 필요없음

- 프로세스가 모니터 안에서 기다릴 수 있도록 하기 위해 condition variable 사용

- condition variable은 wait와 signal 연산에 의해서만 접근 가능

x.wait(); - x.wait()을 invoke한 프로세스는 다른 프로세스가 x.signal을 invoke하기 전까지 suspend 된다.

x.signal(); - x.signal()은 정확하게 하나의 suspend된 프로세스를 resume한다. 

2. Bounded-Buffer Problem

monitor bounded_buffer
{
    int buffer[N]; //공유 버퍼
    condition full, empty; 
    /*condition variable은 값을 가지지 않고, 
    자신의 큐에 프로세스를 매달아서 sleep시키거나 큐에서 프로세스를 깨우는 역할만 함*/
    
    void produce(int x){
        if there is no empty buffer
            empty.wait(); //consume 메소드의 empty.signal()에 의해 깨워짐
        add x to an empty buffer
        full.signal(); //full 버퍼를 기다리는 프로세스를 깨움 
    }
    
    void consume(int* x){
        if there is no full buffer
            full.wait();
        remove an item from buffer and store it to *x
        empty.signal();
    }
}

3. Dining Philosophers Example

Each Philosopher:
{
    pickup(i); //enter monitor
    eat();
    putdown(i) //enter monitor
    think();
} while(1)

 

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); 
        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(); /*wakeup Pi*/
        }
    }
    
    void init(){
        for(int i=0; i<5; i++){
            state[i] = thinking;
        }
    }
}