상호 배제

특정 공유 자원을 한 순간에 하나의 프로세스만 사용할 수 있을 때, 한 프로세스가 공유 데이터에 접근하는 동안 다른 프로세스는 그 데이터에 접근하지 못하게 막는 것을 상호 배제라 한다. 다중 스레드나 프로세스가 공유 자원에 동시에 접근하는 것을 막기 위한 개념으로, 주로 동기화 문제를 해결하는 데 쓰인다. 상호 배제는 임계 구역(크리티컬 섹션) 문제를 다루는데, 임계 구역이란 여러 스레드가 동시에 접근해서는 안 되는 코드 블록을 말한다.

임계 구역(Critical Section)

임계 구역은 프로그램 안에서 공유 자원(데이터 등)에 접근하는 코드 영역이다. 여러 스레드가 동시에 임계 구역에 들어가면 데이터 일관성 문제가 발생할 수 있다.

진입 섹션(Entry Section)

진입 섹션은 스레드가 임계 구역에 들어가기 전에 실행되는 코드다. 이 섹션에서 스레드가 임계 구역에 들어갈 수 있는지 확인하고, 상호 배제를 보장한다.

퇴장 섹션(Exit Section)

퇴장 섹션은 스레드가 임계 구역을 떠난 뒤 실행되는 코드로, 다른 스레드가 임계 구역에 들어갈 수 있도록 열어준다.

자바에서는 Lock 객체로 이 흐름을 구현할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

class Counter {
private int count = 0;
private final Lock lock = new ReentrantLock(); //Lock 객체

//증가 함수
public void increment() {
lock.lock();

try {
count++;
} finally {
lock.unlock();
}
}

//카운트 얻기
public int getCount() {
return count;
}
}

문제점

상호 배제를 구현할 때는 두 가지 문제를 조심해야 한다. **교착 상태(Deadlock)**는 둘 이상의 스레드가 서로 상대방의 락을 기다리며 무한 대기에 빠지는 문제로, 락에 순서를 부여하거나 타임아웃을 설정해 해결한다. **기아(Starvation)**는 특정 스레드가 계속 임계 구역에 진입하지 못하는 문제로, 공정한 락을 사용하거나 우선순위를 할당해 해결한다.