동기화
배경
임계 구역 (Critical Section)
- 코드 일부 중 여러 프로세스들이 한 번씩 접근할 수 있는 구역.
- 프로세스 경쟁 상태가 발생하는 주 원인이기도 하다.
- 코드의 흐름은 진입구역 - 임계구역 - 퇴출구역 으로 되어 있다.
- 임계 구역을 해결하기 위해 아래와 같은 조건들을 충족해야 한다.
- Mutual Exclution (상호 배제) : 이미 한 프로세스가 임계 구역에서 작업 중일 때, 진입이 불가능하다.
- Progress (진행) : 임계 구역에서 작업 중인 프로세스가 없으면 다른 프로세스가 진입할 수 있어야 한다.
- Bounded Waiting (한정 대기) : 임계 구역에서는 무한 대기가 있으면 안 된다.
- 커널은 시스템 자체의 자원을 가지고 있어 임계 구역의 사례로 적합하다.
Peterson 해결법
while (true) {
flag[i] = true;
turn = j;
while (flag[j] && turn == j);
flag[i] = false;
}
- 임계 영역의 문제를 해결할 수 있는 원시적인 방법.
- 2 개의 프로세스들이 번갈아 가면서 실행을 하는 것이 목표이다.
flag
(작업 확인 변수), turn
(진입 요망 변수) 를 사용한다.
- 최신 컴퓨터 아키텍쳐에서 사용하기 힘들다.
- 프로세서 컴파일러가 종속성 없는 읽기, 쓰기 작업을 정렬할 수 있기 때문.
- 정렬 작업은 입, 출금 계산 데이터를 정렬하는 과정과 비슷하다.
- 단일 프로세스에서 결과 값은 유효한데, 다중 프로세서에서는 달라질 수도 있다.
하드웨어 기반 명령어
- 동기화를 해결하기 위해 SW 기법으로 해결하는데 역부족이 있다.
- 대개 워드 (단위) 내용을 원자적으로 교환하는 방식으로 구성되어 있다.
- 아래 두 함수가 대표적으로 사용된다.
- 원자적 연산 방식으로 처리하여 경쟁 상태임에도 불구하고 상호 배제 (Mutual Exclusion) 을 보장한다.
Mutex Locks
- MUTEX : MUTual EXclusion (상호 배제)
- 동기화 도구 중에서 간단한 로직으로 구성되어 있다.
available
(가용성) 을 기준으로 Lock 여부를 결정한다.
acquire()
, release()
함수는 원자적으로 실행이 되어야 한다.
- 프로세스가 Lock 을 기다릴 때, 문맥 교환을 거치지 않고 Lock 이 끝날 때까지 기다리는 현상인 스핀 락 과 유사하다.
- 다중 처리 프로그래밍에서
acquire()
함수를 무한 실행을 하면 바쁜 대기 현상이 일어난다.
- 여기서 Lock 경합 (Contention) 현상이 일어나게 된다.
세마포어 (Semaphore)
wait (S) {
while(S <= 0) {}
S--;
}
signal (S) {
S++;
}
wait (S) {
S--;
if (S < 0) {
queue.offer(S);
}
}
signal(S) {
S++;
if (S <= 0) {
queue.poll();
}
}
- 카운터를 이용하여 리소스에 접근할 수 있는 프로세스를 제한한다.
- 카운터는 이진 (뮤택스 락과 유사), 다중으로 나뉜다.
- 프로세스와 여러 개의 스레드가 임계 영역에 동시에 접근할 수 있다.
- 세마포어의 정수 연산은 원자성을 보장하면서 실행해야 한다.
- 기법 1 에서
wait()
에 인터럽트가 발생되면?
- 인터럽트 진행 시, 원자성이 깨질 수 있다.
- 프로세스의 임계 구역 접근 순서를 책정하기 힘들다.
- 다중 처리 프로그래밍에서 교착 상태 (Deadlock) 가 발생할 수 있다.
- 기법 1 에서
signal()
에 인터럽트가 발생되면?
- 다중 프로세스가 임계 구역에 들어가 상호 배제를 어기게 된다.
- 기법 2 에서 wakeup 기법을 추가로 사용하여 바쁜 대기의 단점을 줄일 수 있다.
모니터 (Monitor)
- Mutex Lock, 세마포어의 타이밍 오류를 최소화해야 한다.
- 특히 고급 언어에서 이러한 현상이 발생할 수 있다.
- ADT (추상 데이터 타입, 데이터의 접근성을 보조.) 를 모니터 객체에 주입 시켜 은닉성을 보장한다.
- 모니터 구조물은 항상 1 개의 프로세스만이 실행할 수 있게 보장되어 있다.
- Java 에서
synchronizd
키워드 사용 시, 모니터 기법을 사용하여 동기화를 제공한다.
- 물론 모니터도 다른 기법들과 마찬가지로 순서를 보장하진 않는다.
- 순서에 맞게 호출 되게끔 보장을 할 수 있는 방법은 있다.
- 이렇게 되면, 규모가 큰 시스템에서는 오히려 불리할 수 있다.
교착 상태 (Deadlock)
- 여러 개의 프로세스들이 대기 중인 프로세스 중 하나로 인하여 무한정 대기가 발생하는 현상이다.
- 군대에서 한 사람의 실수로 연대 책임을 무는 거랑 비슷하다.
- 세마포어에서
wait()
함수에 인터럽트가 발생할 때 이 현상이 발생한다.
- 대부분 프로그래밍 로직의 타이밍이 안 맞게 되어 실행할 때 발생하게 된다.