오퍼레이션을 잘못 사용하면 오류가 발생합니다. 예를 들어
signal(mutex) ….. wait(mutex)
wait(mutex) ….. wait(mutex)
signal()
혹은 wait()
생략이러한 User hazards가 발생할 수 있습니다.
high-level abstraction 입니다. 클래스와 같은 abstrac data type 입니다. procedure 안에서만 내부 변수에 접근할 수 있으며, 오직 하나의 프로세스만 monitor 내에서 작동할 수 있습니다.
→ Mutual exclusion 은 항상 보장됩니다.
monitor monitor-name {
// shared variable declarations
procedure P1 (...) {...}
procedure P2 (...) {...}
...
procedure Pn (...) {...}
initialization code (..) {...}
}
이런 느낌입니다.
semaphore 변수 mutex
를 선언 후 1로 초기화합니다.
semaphore mutex;
mutex = 1;
이후, 각각의 procedure P
내부는 아래처럼 구현됩니다.
wait(mutex);
...
body of P;
...
signal(mutex);
Monitor 내부의 shared data(variables)는 오직 monitor 내부의 procedure 에서만 접근 가능하고, 한번에 하나의 프로세스만 존재할 수 있습니다.
하지만, 특정 조건이 만족될 때까지 대기해야 하는 경우가 발생한다면? 예를 들어 bounded-buffer 문제가 발생하게 되면, 다른 방법을 사용해야 합니다. 따라서 condition x, y;
변수를 생성하고 이를 통해 프로세스의 상태를 관리합니다.
x.wait()
: x.signal()
호출 전까지 실행을 중단시킵니다.x.signal()
: x.wait()
중인 프로세스 하나를 실행합니다.(참고 : x.wait()
중인 프로세스가 없다면, x.signal()
은 아무런 영향을 주지 않습니다.)
entry 큐에서 프로세스가 들어옵니다. 실행 중, x.wait()
시 shared data 영역의 큐에서 정지합니다. 이후, x.signal()
이 호출되면 큐에서 차례대로 하나씩 실행됩니다. 만약 큐가 비어있고 모두 처리했으면, entry 큐에서 다음 프로세스가 입장합니다.
하지만 여기서 고려해야 할 것이 있습니다. x.signal()
호출 시, 뒤에 이어지는 코드를 모두 실행하고 x.wait()
중인 프로세스를 실행할지 아니면 바로 대기중인 프로세스를 실행할지 선택해야 합니다. (병렬로 실행할 수 없기 때문)
두 옵션 모두 장단점이 존재합니다. signal and continue가 합리적이지만, 대기중인 프로세스가 실행될 때 다시 대기해야하는 상황이 나올 수 있으므로 대부분은 signal and wait를 지원합니다.
semaphore mutex = 1;
semaphore next = 0;
int next_count = 0;
이렇게 semaphore 변수를 초기화 합니다. 그리고 대기 중인 프로세스의 개수를 카운트하기 위한 변수 1개를 추가로 생성합니다.
그리고, 각 함수에서는 다음처럼 구현하게 됩니다.
wait(mutex);
...
body of P;
...
if (next_count > 0)
signal(next);
else
signal(mutex);
signal(next)
: 대기중인 프로세스가 있을 경우, 해당 프로세스를 실행합니다. (next_count가 프로세스 넘버를 뜻합니다)signal(mutex)
: 대기중인 프로세스가 없을 경우, 모니터 밖에서 대기중인 프로세를 실행합니다.condition variable x를 추가합니다.
semaphore x_sem; //init = 0
int x_count = 0;
그리고 condition variable x의 x.wait()
, x.signal()
의 구현은 다음과 같습니다.
//x.wait()
x_count++;
if (next_count > 0)
signal(next);
else
signal(mutex);
wait(x_sem);
x_count--;
//x.signal()
if (x_count > 0) {
next_count++;
signal(x_sem);
wait(next);
next_count--;
}
semaphore와는 달리, 조건 변수의 wait는 특정 조건이 siganl이 되길 기다리는 것이며, signal은 특정 조건을 signal하고 대기하는 것입니다.