💡 프로세스를 동기화하지 않으면 겉보기에 아무런 문제 없어 보이는 코드도 예끼치 못하게 작동할 수 있다. 동기화를 위한 대표적인 도구인 뮤텍스락, 세마포, 모니터에 대해 알아보자
뮤텍스 락(Mutex lock: MUTual EXclusion lock)
- 상호배제를 위한 동기화 도구로 동시에 접근하면 안되는 자원에 프로세스이다. 스레드의 동시접근을 막는다.
- 임계구역이 비었을 때 임계구역에 진입하는 프로세스는 뮤텍스 락을 이용해 임계구역에 자물쇠를 걸어둔다.
- 다른 프로세스는 임계구역이 잠겨 있으면 기다리고, 비게 되면 뮤텍스 락을 걸고 임계구역에 진입한다.
뮤텍스 락의 구현
- 하나의 전역 변수와 2개의 함수로 구현된다.
- 임계구역의 자물쇠 역할로 프로세스들이 공유하는 전역 변수 lock
- 임계구역을 잠그는 함수 acquire
- 임계구역의 잠금을 해제하는 함수 release
acquire 함수
- 프로세스가 임계구역에 진입 전 호출한다.
- 임계 구역이 잠겨 있으면 열릴 때 까지(lock이 false가 될 때 까지) 임계 구역을 반복적으로 확인한다.
- 임계 구역이 열려 있으면 임계 구역을 잠근다(lock을 true로 바꾼다).
release 함수
- 프로세스가 임계 구역에서 작업을 끝내고 호출하는 함수이다.
- 잠긴 임계 구역을 열어주는 함수 (lock을 false로 바꾼다.)
acquire() {
while (lock == true) // 만약 임계 구역이 잠겨 있다면
; // 임계 구역이 잠겨 있는지를 반복적으로 확인
lock = ture; // 만약 임계 구역이 잠겨 있지 않으면 임계 구역을 잠금
}
release() {
lock = false; // 임계 구역 작업이 끝났으니 잠금 해제
}
- acquire와 release함수를 아래와 같이 임계 구역 전후로 호출함으로써 하나의 프로세스만 임계 구역에 진입할 수 있다.
acquire(); // 자물쇠 잠겨 있는지 확인, 잠겨 있지 않으면 잠그고 들어가기
// 임계 구역 // 임계 구역에서의 작업 진행
release(); // 자물쇠 반환
- 앞서 언급했던 생산자 소비자 문제를 아래와 같이 뮤텍스로 구현한다면?
acquire();
// '총합' 변수 접근
release();
뮤텍스 락 정리
- 락을 획득할 수 없으면 (임계 구역 진입할 수 없다면) 무작정 기다린다.
- 락을 획득할 수 있으면 (임계 구역 진입할 수 있다면) 임계 구역을 잠근 뒤 임계 구역에서 작업을 진행한다.
- 임계 구역을 빠져 나올 땐 임계 구역 잠금을 해제한다.
- 위의 과정을 실행함으로써 임계구역을 보호할 수 있다.
while(lock == true) // 만약 임계 구역이 잠겨 있다면
; // 임계 구역이 잠겨 있는지를 반복적으로 확인
- 반복적으로 상태가 변경되었는지 확인하며 대기하는 방식을 바쁜 대기(busy wait)라고 한다.
뮤텍스 락의 한계
- 사용할 수 있는 공유 자원이 없으면 프로세스는 무한히 반복하며 공유 자원 사용 가능 여부를 확인해야 한다.
- 즉, 바쁜 대기 상태로 CPU의 주기를 낭비하게 된다.
세마포(semaphore)
- 뮤텍스 락보다 조금 더 일반화된 동기화 도구
- 공유 자원이 여러 개 있는 상황에서도 적용이 가능하다.
- 철도 신호기에서 세마포란 단어가 유래되었다.
세마포의 종류
- 세마포의 종류에는 이진 세마포와 카운팅 세마포가 있다.
- 이진 세마포(binary semaphore): 뮤텍스 락과 비슷한 개념. 공유 자원이 하나를 말한다.
- 카운팅 세마포(counting semaphore): 공유 자원이 여러 개일 때를 뜻한다.
세마포의 구현
- 하나의 전역 변수와 두개의 함수로 구현된다.
- 임계 구역 진입 가능 프로세스 개수 (사용 가능 공유 자원 개수)를 나타내는 전역 변수 S
- 임계 구역에 들어가도 좋은지, 기다려야 하는지를 확인하는 wait 함수
- 임계 구역에서 기다리는 프로세스에 진입이 가능하다고 신호를 주는 signal 함수
wait()
// 임계구역
signal()
# wait 함수
wait () {
while (S <= 0 ) // 1
; // 2
S--; // 3
}
- 1 : 임계 구역에 진입할 수 있는 프로세스 개수가 0개 이하라면
- 2 : 사용할 수 있는 자원이 있는지를 반복 확인
- 3 : 임계 구역 진입 가능 프로세스가 1개 이상이면 S를 1 감소시키고 임계구역 진입
# signal 함수
signal () {
S++ // 1
}
- 1 : 임계 구역에서 작업을 마친 후 S를 1 증가 시킨다.
wait()
// 임계 구역
signal()
세마포의 대기 극복
- 세마포는 wait 함수에서 사용 가능 자원이 없을 때 프로세스를 대기상태로 만들어 바쁜 대기를 방지한다.
- 프로세스의 PCB를 대기 큐에 집어넣고, signal 함수 호출을 대기한다.
- 다른 프로세스가 임계 구역 작업이 끝나고 signal 함수를 호출하면, signal 함수는 대기 중인 프로세스를 대기 큐에서 제거한다.
- 대기 큐에서 제거된 프로세스는 준비 상태로 변경되고 준비 큐로 이동된다.
# 변경된 wait 함수
wait () {
S--;
if ( S < 0 ) {
add process p to Queue; // 1. 해당 프로세스 PCB를 대기큐에 삽입한다.
sleep(); // 2. 대기 상태로 접어든다
}
}
# 변경된 signal 함수
signal () {
S++
if (S <= 0 ) {
remove a process p from Queue // 1. 대기 큐에 있는 프로세스 p 제거한다.
wakeup(p) // 2. 프로세스 p를 대기 상태에서 준비 상태로 만든다.
}
}
모니터(monitor)
- 세마포에 비하면 사용자가 사용하기에 훨씬 편리한 도구이다.
- 공유 자원과 공유 자원에 접근하는 인터페이스(통로)를 묶어서 관리한다.
- 프로세스는 반드시 인터페이스를 통해서만 공유 자원에 접근한다.
- 인터페이스에 접근할 프로세스는 큐(모니터에 진입하기 위한 큐)에 삽입되고, 모니터 내에는 항상 하나의 프로세스만 들어오도록 하여 상호배제를 위한 동기화를 실현한다.
- 조건 변수를 통해 특정 조건을 바탕으로 프로세스 실행 및 일시 중단하여 실행 순서를 위한 동기화를 실현한다.
- 프로세스나 스레드 실행 순서를 제어할 때 사용하는 변수를 조건 변수(conditional variable)라고 한다.
모니터의 조건 변수
- 모니터가 조건 변수를 사용한다고 하지만, 조건변수와 모니터는 별개의 개념이다.
- 조건 변수는 wait과 signal 연산을 수행할 수 있다.
- wait는 호출한 프로세스 상태를 대기 상태로 전환하고 일시적으로 조건 변수에 대한 대기 큐에 삽입하는 연산이다.
💡 상호 배제를 위한 큐와 조건 변수에 대한 대기 큐는 다르다.
- 전자는 모니터에 한 번에 하나의 프로세스만 진입하도록 만들어진 큐이고, 후자는 모니터에 이미 진입한 프로세스의 실행 조건이 만족될 때 까지 잠시 실행이 중단되어 기다리기 위해 만들어진 큐이다.
- 조건변수는 여러가지가 있을 수 있다.
- ex) 특정 프로세스가 모니터에 들어오고 x.wait()가 호출되면 조건 변수 x가 만족할 때까지 대기한다.
- wait 연산으로 실행이 일시 중지된 프로세스는 다른 프로세스의 signal 연산을 통해 실행이 재개될 수 있다.
- ex) x.signal은 조건변수 x 대기 큐에 삽입된 프로세스 실행을 재개하는 함수이다.
모니터에서 프로세스의 실행 조건
- wait을 호출했던 프로세스는 signal을 호출한 프로세스가 모니터를 떠난 뒤 실행될 수 있다.
- signal을 호출한 프로세스의 실행을 일시 중단하고 자신이 실행된 뒤 다시 signal을 호출한 프로세스의 수행을 재개한다.
💡 중요한 점은 모니터는 조건 변수를 이용하여 아래와 같은 프로세스 실행 순서 제어를 위한 동기화를 제공한다는 사실이다.
모니터의 프로세스 실행 순서 제어 동기화
- 특정 프로세스가 아직 실행될 조건이 되지 않으면 wait를 통해 실행을 중단한다.
- 특정 프로세스 실행 조건이 충족된 경우, signal을 통해 실행을 재개한다.
[문제] 다음 중, 틀린 개념을 고르시오.
- 뮤텍스 락은 임계 구역을 잠금으로써 프로세스 간의 상호 배제를 이룬다.
- 세마포는 공유 자원이 여러 개 있는 임계 구역 문제도 해결할 수 있는 동기화 도구다.
- 모니터는 세마포에 비해 사용자가 사용하기 편리한 동기화 도구로 조건 변수를 사용한다.
- 모니터가 조건 변수를 사용함으로 조건변수와 모니터는 동일한 개념이다.
[정답] 4. 모니터가 조건 변수를 사용하지만, 둘은 별개의 개념이다.