본문 바로가기

CS 과목(CS科目)/운영체제(OS)

모니터(monitor)(sub: 그 모니터 아닙니다 ㅋㅋ)

모니터

1. mutual exclusion을 보장

2. 조건에 따라 스레드가 대기(waiting) 상태로 전환 가능

 

모니터는 언제 사용되나?

1. 한번에 하나의 스레드만 실행돼야 할 때(mutual exclusive)

2. 여러 스레드와 협업(cooperation)이 필요할 때!

 

모니터의 구성 요소

1.mutex

2.condition variable(s) : waiting queue를 가지며, 그 안에 조건이 충족되길 기다리는 스레드들이 대기 상태로 머무는 곳!

 

condition variable에서 주요 동작(operation)

1. wait : thread가 자기 자신을 condition variable의 waiting queue에 넣고 대기 상태로 전환

2. signal : waiting queue에서 대기 중인 스레드 중 하나를 꺠움

3. broadcast : waiting queue에서 대기 중인 스레드 전부를 깨움

 

 

while(!p){

wait( m,cv )

}

-> 조건(p)를 만족시키지 못하는 스레드는 Condition Variable(CV)가 관리하는 Waiting Queue에 들어가서 대기 상태가

된다.

m(뮤텍스)가 매개변수로 들어 가는 이유는

대기 상태로 들어간 스레드는 더 이상 lock을 쥐고 있으면 안 되기 때문이다.

또한 시간이 흘러서, Waiting Queue에 들어간 스레드가 다시 활성화 됐을 때, 다시 m(뮤텍스)를 통해 lock 획득을 시도해

야 하기 때문이다.

signal(cv2) or broadcase(cv2)

-> critical section의 코드들을 실행을 하다가 waiting queue에 있던 스레드들이 조건을 충족하게 될 수도 있다.

이때, waiting queue에 있는 스레드를 깨워 줘야 하는데,

만약 1개의 스레드만 깨운다면 signal(cv2)를 호출하고

전부의 스레드를 꺠운다면 broadcast(cv2)가 호출이 된다.

 

모니터 = ENTRY queue(critical section에 진입을 기다리는 큐) + WAITING queue(조건이 충족되길 기다리는 큐)

 

모니터의 사용 예시(bounded producer/consumer problem)

생산자/소비자 문제

 

case1] producer가 buffer에 아이템을 담으려고 하는데, 이미 buffer는 꽉 찼다. 이때, producer는 무한 루프를 돌려서 buffer에 빈 곳이 있는지 없는지를 계속 확인해야 한다.

case2] 반대로, consumer가 buffer에 있는 ITEM을 소비하려고 하는데, buffer에 아이템이 하나도 없다. 이때 consumer가 버퍼에 아이템이 있는지 없는지 계속 확인해야 한다.

-> 위와 같이 계속 확인해야 하는 문제를 모니터를 통하여 해결이 가능하다. 

 여기서 Buffer q는 producer()과 consumer()에서 공유되는 데이터이기 때문에 각 method안의 critical section 안에서

mutual exclusive가 보장이 돼야 한다. mutual exclusive가 보장이 안 되면 race condition이 발생한다.

 

코드 분석 : 

case1의 경우, producer()를 실행 중인 스레드를 waiting queue에 넣어 , 조건을 충족( buffer가 빌 때)할때 까지 대기 상태에 둔다. 

그러다 consumer()가 실행이 되고, 꽉 차있는 buffer q를 하나씩 소비하여 producer의 waiting queue에게 signal or

broadcast()을 통해 조건이 충족(buffer가 비었다는 것)된 것을 알려서 대기 상태의 스레드를 깨워서 나머지 critical section

을 실행하게 한다.  

case2의 경우 : consumer()를 실행 중인 스레드를 waiting queue에 넣어, 조건을 충족(buffer에 아이템이 하나라도 있을 때)

할 때까지 대기 상태에 둔다.

그러다 producer()이 실행이 되고, 비어 있는 buffer에 아이템을 하나씩 넣어, consumer의 waiting queue에게 signal or

broadcast()을 통해 조건이 충족(buffer에 아이템이 하나라도 있다)된 것을 알려서 대기 상태의 스레드를 깨워, 나머지

critical section을 실행하게 된다. 

(구체적인 실행 순서는 동영상을 참조하라)

 

모니터는 프로그래밍 언어에서 이미 지원되고 있다.

이러한 이유로 개발자가 모니터를 구현할 일은 전혀 없다. 

그러나 이번 시간에는 JAVA에서는 모니터가 어떻게 구현되는지 간략히 알아 보자. 

 

JAVA에서 모든 객체는 내부적으로 모니터를 가진다. 

1. 모니터의 mutual exclusion 기능은 synchrnozied 키워드로 사용한다.

2. JAVA의 모니터는 condirtion variable을 하나만 가진다. ( 두 개 이상의 cv를 원한다면 따로 구현이 필요)

3. JAVA 모니터의 세 가지 동작(Operation)

a) wait

b) notify(=signal)

c) notifyAll(=broadcast)

 

bounded producer/consumer problem WITH JAVA

 

java.util.concurrent에는 동기화 기능이 탑재된 여러 클래스들이 있으니 참고하자.