동기화(synchronization), 경쟁 조건(race condition), 임계 영역(critical section)

이다혜·2024년 3월 21일
0

영상후기

목록 보기
12/12

동기화가 없으면 생길 수 있는 일

하나의 객체를 두 개의 스레드가 접근할 때 생기는 일에 대해 알아보자.

두 개의 귤 박스(스레드)에서 상한 귤을 골라낸다고 해보자.

for (귤 in 귤박스) {
    if (귤 상태 is 불량) {
       badCounter.increment();
    }
 }
public class Conter {
   private int state = 0;
   public void increment() { state++; }
   public int get() { return state; }
}

귤 박스에 있는 귤의 상태가 불량이면 state를 증가시키는데, 이 때 badConter는 두 스레드가 공유하는 객체이다. 그래야 두 박스를 합쳐서 불량인 귤의 전체 수를 구할 수 있다.

state 증가가 CPU에서 동작하는 방식

LOAD state to R1 // state의 값을 레지스터에 가져온다.
R1 = R1 + 1 // 레지스터에 있는 값을 1 증가시켜서 저장한다.
STORE R1 to state // 레지스터의 값을 메모리의 state에 저장한다.

우리는 스레드1에서 5개의 귤을 발견하고, 스레드2에서 2개의 귤을 발견하면 state가 7이 될것이라고 기대한다.

하지만, 한 스레드에서 증가한 state의 값이 아직 메모리에 반영 되지 않았을 때 컨텍스트 스위칭이 일어나게 되면 다른 스레드에서는 아직 증가하지 않은 state의 값을 가지고 명령을 시작하게 된다.

이렇게 언제 컨텍스트 스위칭이 일어나느냐에 따라 결과가 달라지고 기대와 다른 값이 나오게 된다.


💡경쟁 조건(race condition)

이렇게 여러 프로세스/스레드가 동시에 공유된 자원에 접근(조작)할 때 타이밍이나 접근 순서에 따라 결과가 달라질 수 있는 상황을 경쟁 조건(race condition)이라고 한다.

💡동기화(synchronization)

여러 프로세스/스레드를 동시에 실행해도 공유 데이터의 일관성을 유지하는 것


어떻게 동기화 시킬 것인가?

프로그래밍 언어 레벨에서의 state++라는 명령문이 실제로 CPU에서 실행될 수 있는 명령어 레벨에서 봤을 때는 단일 명령문이 아니라 3가지의 명령문의 조합이다.

❓그러면 이 3가지의 명령문을 실행하는 도중에는 컨텍스트 스위칭이 일어나지 않도록 하면 될까?

➡️ 이 방법은 싱글 코어에서는 가능하지만 멀티코어에서는 두 스레드가 동시에 실행되기 때문에 불가능하다.

increment() 메서드를 한 번에 한 스레드만 실행할 수 있도록 하면 된다.
다른 스레드가 메서드를 실행하려고 해도 이미 해당 메서드를 실행중인 스레드가 있으면 메서드 호출을 끝낼 때까지 기다리게 한다.


💡임계 영역(critical section)

공유 데이터의 일관성을 보장하기 위해 하나의 프로세스/스레드만 진입해서 실행 가능한 영역


임계 영역 문제를 해결하는 뼈대

do {
  entry section // 임계 영역에 진입하기 전에 조건을 확인하는 영역
     critical section // 임계 영역
  exit section 
     remainder section
} while(TRUE)

임계 영역 문제의 해결책이 되기 위한 조건

1. mutual exclusion(상호 배제)
한 번에 하나의 프로세스/스레드만 임계 영역에서 실행한다.

2. progress(진행)
만약에 임계 영역이 비어있고 임계 영역에 들어가기 원하는 프로세스/스레드가 있다면, 그 중에 하나는 임계 영역에서 실행될 수 있도록 해야한다.

3. bounded waiting(한정된 대기)
무한정 임계 영역에 들어가지 못하고 기다리게 하면 안된다.


0개의 댓글