모니터
세마포어의 문제점
- 올바른 프로그램 작성의 어려움
semWait,semSignal연산이 프로그램 전체에 산재함 ⇒ 어떠한 영향을 미치는지 파악이 어려움
모니터를 이용한 병행 제어
- Concurrent Pascal, Pascal-Plus, Modula-2, Modula-3, Java
- 언어 수준 혹은 라이브러리 수준에서 구현
- java의 경우 →
synchronized키워드로 락 걸기
- java의 경우 →
- 보호하려는 어떠한 객체에도 모니터 락(lock) 설정 가능
- java의 경우 → 만든 객체에 락을 설정/해제가 가능. 연결 리스트 전체를 가리키는 객체를 만들고 설정하면 전체에 대해 락을 걸 수 있음
- 모니터에 진입하게 되면 락을 걸어야 하는지 확인
유한 버퍼에서 모니터를 이용한 생산자/소비자 문제 해결 방법
produce와 take 함수
/* 생산자 소비자 프로그램 */
monitor boundedbuffer; /* 데이터를 저장하고 꺼내가는 곳 */
char buffer (N); /* N개의 문자가 저장될 수 있는 버퍼 */
int nextin, nextout; /* 버퍼 포인터 */
int count; /* 버퍼 내부에 추가된 문자 개수 */
cond notfull, notempty /* 동기화를 위한 조건 변수 */
void append(char x)
{
if (count == N) cwait(notfull); /* 버퍼에 문자가 가득 찬 경우, 오버플로우 감지 => 기다림 */
/* 생산자 코드 */
buffer(nextin) = x;
nextin = (nextin + 1) % N;
count++;
/* 버퍼에 문자 하나를 추가 */
csignal(notempty); /* notempty 조건 변수에서 대기하고 있는 프로세스를 깨움*/
}
void take(char x)
{
if (count == 0) cwait(notempty); /* 버퍼가 빈 경우, 언더플로우 방지*/
/* 데이터를 꺼내는 코드 */
x = buffer(nextout);
nextout = (nextout + 1) % N;
count--; /* 버퍼에서 문자 하나를 삭제 */
/* 데이터를 꺼내고 하나가 비면 다른 하나가 다시 차길 기다림 */
csignal(notfull); /* notfull 조건 변수에서 대기하고 있는 프로세스를 깨움 */
}
{ /* 모니터 몸체 */
nextin = 0; nextout = 0; count = 0; /* 버퍼 변수 초기화 */
}void producer()
{
char x;
while (true) {
produce(x);
append(x);
}
}
void consumer()
{
char x;
while (true) {
take(x);
consume(x);
}
}
void main()
{
parbegin(producer, consumer)
}