프로세스가 서로 협력하여 공유 자원을 사용할 때, 경쟁 조건이 발생하면 공유 자원을 신뢰할 수 없게 만들 수 있다. 이를 방지하기 위해 프로세스들이 공유 자원에 접근하려고 할 때 프로세스들의 순서를 정하여 데이터의 일관성을 유지시키는 것이 프로세스 동기화이다.
Race Condition(경쟁 조건)
: 여러 프로세스(또는 스레드)가 공유 자원에 동시에 접근할 때, 공유 자원에 대한 접근 순서에 따라 실행 결과가 달라질 수 있는 상황이다. 동시에 접근할 때 자료의 일관성을 해치는 결과가 나올 수 있다. 대표적으로 다음 세 상황에서 경쟁 조건이 발생할 수 있다.
Critical Section(임계 구역)
: 여러 프로세스(또는 스레드)가 자원을 공유하는 상황에서, 하나의 프로세스(스레드)만 접근할 수 있도록 제한해둔 코드 영역이다. 임계 구역에서 경쟁 조건이 발생할 수 있다. 임계 구역으로 인해 발생하는 문제(Critical Section Problem, CSP)들을 해결하기 위해 다음 조건들을 만족해야 한다.
Mutex(Mutual Exclusion) Lock
동시에 공유 자원에 접근하는 것을 막기 위해 임계 구역에 진입하는 프로세스는 acquire()함수를 통해 Lock을 획득하고, 임계 구역을 빠져나올 때 release() 함수를 통해 Lock을 반환함으로써 동시 접근을 방지한다.
available 이라는 변수는 Lock의 가용 여부를 나타낸다. Lock이 가용 상태이면 acquire()호출이 성공하고 Lock은 사용 불가 상태가 된다. 사용 불가 상태의 Lcok을 획득하려고 시도하는 프로세스는 Lock이 반환될 때까지 봉쇄된다.
이러한 방식은 임계 구역에 들어가기 전에 Lock을 얻기 위해 acquire() 함수에서 무한 루프에 빠져 CPU cycle을 낭비하게 되는 Busy Waiting의 단점이 있다.
Mutex Lock 유형을 Spinlock이라고도 하는데, 이는 Lock을 사용할 수 있을 때까지 프로세스가 기다리면서 계속 회전하기 때문이다.
Semaphore(세마포어)
세마포어는 Busy Waiting이 필요 없는 동기화 도구이며, 여러 프로세스나 스레드가 임계 구역에 진입할 수 있는 Signaling 메커니즘이다.
사용 가능한 자원의 개수를 주로 S라는 변수로 나타내며, wait() 함수(P)와, signal() 함수(V)로만 접근 가능하다. 이 때, S값을 변경하는 연산은 반드시 원자적으로 수행되어야 한다.
wait(S) {
S--;
if(S < 0){
add this process to S.L;
block();
}
}
signal(S) {
S++;
if(S <= 0){
remove a process P from S.L;
wakeup(P);
}
}
L은 block된 프로세스들이 기다리는 Queue이다. Block을 수행하면 커널은 block을 호출한 프로세스를 중단시키고 해당 프로세스의 PCB를 Wait Queue에 넣어준다. Wakeup을 수행하면 block된 프로세스 P를 깨워서 이 프로세스의 PCB를 Ready Queue로 이동시킨다.
S가 0 이상의 정수값을 가질 경우 Counting Semaphore로 주로 자원의 개수를 세는 데 사용되며, 0과 1 값만 가질 경우 Binary Semaphore로 Mutex Lock과 동일한 역할을 한다.
코딩하기가 힘들고 실수하기 쉬우며, 정확성을 입증하기 어렵다.
Moniter(모니터)
세마포어의 단점을 보완하기 위한 High-level 동기화 구조이다. 공유 자원에 접근하기 위해서는 모니터의 내부 Procedure을 통해서만 접근할 수 있다.
세마포어는 프로그래머가 직접 wait과 signal 함수를 통해 Lock을 이용하여 경쟁 조건을 해결하지만 모니터는 자체적인 기능으로 해결할 수 있어 Lock을 이용할 필요가 없다.
모니터에 진입하지 못한 프로세스들은 모니터 큐에서 대기한다. 이 때, Condition Variable(조건 변수)을 사용하여 순서를 보장받는다. 조건 변수는 wait과 signal연산 만으로 접근 가능하며, 어떤 값을 가지진 않지만 자신의 큐에 프로세스를 매달아서 sleep 시키거나 큐에서 프로세스를 깨우는 역할을 한다.