세마포 또는 mutex 락을 이용하여 임계구역 문제를 해결할 때 문제점 → 프로그래머가 세마포를 잘못 사용할 시, 다양한 유형의 오류가 쉽게 발생할 수 있음
이러한 오류 처리를 위해 모니터 사용
전략 : 간단한 동기화 도구를 통합하여 고급 언어 구조물로 제공하는 것 → 모니터
모니터는 근본적인 고급 언어 구조물 중 하나
Java, C# 등의 많은 프로그래밍 언어들이 모니터의 개념을 편입시킴
모니터 사용법(Usage)
ADT와 모니터
ADT(추상화된 데이터 형) : 데이터와 해당 데이터를 조작하는 함수들의 집합을 하나의 단위로 묶어 보호
이때 함수의 구현은 ADT의 특정한 구현과는 독립적
모니터 형 : 모니터 내부에 프로그래머가 정의한 일련의 연산자 집합을 포함하는 ADT
이때 모니터 내부에서 상호배제가 보장되어야 한다.
변수들의 선언을 포함하고, 이 변수들의 값은 그 형에 해당하는 한 인스턴스의 상태를 정의
모니터형은 해당 변수를 조작할 수 있는 프로시저/함수 본체도 같이 포함
모니터 코드 구문과 개략도
mointor monitor name
{
/* 공유 변수 선언 */
function P1(...){
...
}
function P2(...){
...
}
.
.
.
function Pn(...){
...
}
initialization_code(...){
...
}
}
모니터 형의 표현은 다른 프로세스들이 직접 사용할 수 없다. → 오직 모니터 내에 정의된 함수만 모니터 내에 지역변수와 형식 매개변수들에게 접근 가능
모니터 구조물은 모니터 안에 항상 하나의 프로세스만이 활성화되도록 보장 → 프로그래머들은 동기화 제약 조건을 명시적으로 코딩할 필요가 없다.
모니터 개략도
모니터 구조물 동기화 기법 정의
위에서의 모니터 구조물은 어떤 동기화 기법을 모델링하는데 충분하지 않다. → 이를 위해 부가적인 동기화 기법 정의가 필요
동기화 기법들은 condition이라는 구조물로 제공
프로그래머는 동기화 기법 작성이 필요할 때, 하나 이상의 condition형 변수를 정의할 수 있다.
ex ) condition x, y;
condition형 변수에 호출될 연산은 wait()와 signal() 밖에 없다.
x.wait()를 호출한 프로세스는 다른 프로세스가 x.signal()을 호출할 때까지 일시중지
x.signal() : 정확히 하나의 일시 중지 프로세스를 재개
일시 중지된 프로세스가 없다면, 해당 연산은 아무런 효과 없음 → x의 상태는 연산이 전혀 실행되지 않는 것과 같음
cf ) 세마포의 signal() 연산은 항상 세마포의 상태에 영향을 준다.
모니터에서 두 프로세스의 동시성
가정
x.signal() 연산이 프로세스 P에 의해 호출될 때, 조건 x와 연관된 일시 중지된 프로세스 Q가 있다고 가정
일시 중지된 스레드 Q가 실행을 재개하면, signal을 보낸 스레드 P는 반드시 대기해야 함 ← 두 프로세스가 동시에 활성화되는 것을 막기 위해
두 프로세스는 개념적으로 실행을 멈추지 않고 계속할 수 있다. → 2가지 가능성 존재
Signal and wait : P는 Q가 모니터를 떠날 때까지 대기 혹은 다른 조건을 기다림
Signal and continue : Q는 P가 모니터를 떠날 때까지 대기 혹은 다른 조건을 기다림
문제점 : P가 계속 실행되고 Q가 기다린다면, Q가 원하는 논리적 조건이 참이 아닐 수 있게 됨
두 가지 방법의 절충안 존재
스레드 P가 signal() 연산을 실행하면, 즉시 모니터를 떠나고 Q가 재개됨
세마포를 이용한 모니터의 구현
각 모니터마다 mutex라는 이진 세마포가 정의되고 초기값은 1
프로세스는 모니터에 들어가기 전 wait(mutex)를 실행
프로세스는 모니터를 나온 후에 signal(mutex)를 실행
모니터 구현 시 signal-and-wait기법을 사용
Signaling 프로세스는 next라는 이진 세마포가 추가로 필요함
이때, next 이진 세마포는 0으로 초기화된다. ← 실행 재개되는 프로세스가 모니터를 떠나든지, wait() 할 때까지 자신이 다시 기다려야 하기 때문
Signaling 프로세스는 자신을 중단시키기 위해 next를 사용할 수 있다.
정수형 변수 next_count는 next에서 일시 중지 되는 프로세스의 개수를 세기 위해 제공
모니터 안에서 상호 배제를 보장하는 코드 구현
wait(mutex);
...
body of F
...
if(next_count > 0) // 일시 중지 중인 프로세스가 있다면
signal(next); // 그 프로세스를 깨움
else // 일시 중지 중인 프로세스가 없다면
signal(mutex); // 모니터에서 나옴