콘텐츠로 이동

Synchronization

다중 프로그래밍 환경에서 여러 프로세스나 스레드가 제한된 자원을 공유하며 실행될 때, 데이터의 일관성을 유지하고 실행 순서를 제어하는 메커니즘이다.

동기화는 크게 두 가지 관점에서 실행 흐름을 제어한다.

  • 실행 순서 제어: 프로세스들이 올바른 순서대로 실행되도록 조정 (예: Reader 프로세스는 Writer 프로세스가 데이터를 다 쓴 후 작업)
  • 상호 배제 (Mutual Exclusion): 동시에 접근해서는 안 되는 공유 자원에 대해 한 번에 하나의 프로세스만 접근하도록 통제

공유 자원과 임계 구역 (Critical Section)

섹션 제목: “공유 자원과 임계 구역 (Critical Section)”
  • 공유 자원 (Shared Resource): 여러 프로세스가 공동으로 이용하는 변수, 메모리, 파일 등의 자원
  • 임계 구역 (Critical Section): 공유 자원에 접근하는 코드 영역으로, 두 개 이상의 프로세스가 동시에 실행하면 안 되는 구역
  • 경쟁 상태 (Race Condition): 여러 프로세스가 동기화 없이 임계 구역에 동시 접근하여, 자원의 최종 값이 실행 순서 (타이밍)에 따라 달라지는 문제 상황

임계 구역 문제 해결의 3가지 조건

섹션 제목: “임계 구역 문제 해결의 3가지 조건”

운영체제가 임계 구역 문제를 해결하고 데이터 일관성을 보장하기 위해서는 다음 세 가지 조건이 반드시 충족되어야 한다.

  1. 상호 배제 (Mutual Exclusion): 한 프로세스가 임계 구역에서 실행 중이면, 다른 어떤 프로세스도 해당 구역에 진입할 수 없음
  2. 진행 (Progress): 임계 구역이 비어있고 진입하려는 프로세스가 있다면, 잔류 중인 프로세스가 없는 한 즉시 진입 허용 (데드락 방지)
  3. 유한 대기 (Bounded Waiting): 프로세스가 임계 구역 진입 요청을 한 후부터 승인될 때까지 다른 프로세스들이 진입 횟수 제한 (기아 현상 방지)
flowchart LR
Start([프로세스 시작]) --> EntrySection[진입 구역: 잠금 시도]
EntrySection --> CriticalSection[임계 구역: 공유 자원 사용]
CriticalSection --> ExitSection[퇴출 구역: 잠금 해제]
ExitSection --> RemainderSection[나머지 구역]
RemainderSection --> Start

운영체제에서는 프로세스 및 스레드 동기화를 위해 다양한 기법을 제공한다.

가장 기초적인 동기화 도구로, 공유 자원에 한 번에 하나의 스레드만 진입하도록 문을 잠그는 (Lock) 방식이다.

  • 락이 잠겨 있으면 락이 풀릴 때까지 스레드가 CPU를 점유한 채 반복문 (루프)을 돌며 무한정 대기 (Busy Waiting)
  • 컨텍스트 스위칭 (Context Switching) 비용이 발생하지 않음
  • 락을 기다리는 동안 CPU 사이클을 의미 없이 낭비하게 됨

스핀락의 CPU 낭비 단점을 보완하여, 대기 큐 (Wait Queue)와 수면 상태 (Sleep)를 활용하는 동기화 기법이다.

  • 락을 획득하지 못한 스레드는 루프를 돌지 않고 대기 상태 (Sleep)로 전환되어 CPU 제어권을 양보
  • 자원 사용이 끝난 스레드가 락을 해제 (Unlock)하며 대기 중인 스레드를 깨워줌 (Wakeup)
  • 상호 배제 (Mutual Exclusion)를 보장하며 단일 자원 관리에 특화됨
  • 반드시 락을 획득한 (소유권이 있는) 스레드만이 락을 해제할 수 있음

단일 자원 잠금을 넘어, 다수의 자원 관리 및 실행 순서 제어 (Signaling)까지 가능한 범용 동기화 기법이다.

  • 내부적으로 가용한 자원의 개수 (정수 변수)를 추적함
  • P(Wait) 연산: 자원을 요청하여 카운트를 1 감소시킴 (0이면 대기 큐로 이동해 Sleep 상태로 전환)
  • V(Signal) 연산: 자원 사용을 마치고 카운트를 1 증가시키며 대기 중인 스레드를 깨움
  • 다수의 스레드가 제한된 수량의 자원에 접근할 수 있도록 허용함 (카운팅 세마포어)

기법 간 차이점 및 적용 방법 (트레이드오프)

섹션 제목: “기법 간 차이점 및 적용 방법 (트레이드오프)”

스레드를 직접 구현할 때는 임계 구역의 길이와 작업 목적에 따라 적절한 도구를 선택해야 한다.

스핀락 vs 뮤텍스 (대기 방식의 트레이드오프)

섹션 제목: “스핀락 vs 뮤텍스 (대기 방식의 트레이드오프)”
  • 스핀락을 적용하는 경우
    • 임계 구역에서의 작업이 매우 짧아, 락을 기다리며 도는 시간 (Busy Waiting)이 스레드를 재우고 깨우는 컨텍스트 스위칭 비용보다 적을 때 유리
    • 주로 운영체제 커널 내부의 짧은 인터럽트 처리 등 제한적인 환경에서 사용
  • 뮤텍스를 적용하는 경우
    • 임계 구역에서의 작업이 길거나 (I/O 작업 등) 언제 끝날지 예측하기 어려워, 다른 스레드에게 CPU를 양보하는 것이 효율적일 때 적용
    • 일반적인 애플리케이션 레벨의 다중 스레드 프로그래밍에서 기본적으로 사용

뮤텍스 vs 세마포어 (사용 목적의 차이)

섹션 제목: “뮤텍스 vs 세마포어 (사용 목적의 차이)”

두 기법 모두 대기 큐를 사용하지만, 소유권과 관리 범위에서 결정적인 차이가 있다.

특징뮤텍스(Mutex)세마포(Semaphore)
소유권락을 획득한 스레드만 락 해제 가능소유권이 없으며 누구나 해제 가능
관리 범위단일 자원 관리다수의 자원 관리 가능
사용 목적상호 배제 (Locking)접근 제어 및 실행 순서 제어 (Signaling)
  • 뮤텍스의 적용 (Locking): 하나의 변수나 파일에 접근할 때 데이터 오염을 막기 위해 꽉 쥐고 (잠금) 놓아주는 (해제) 순수 상호 배제 목적으로 사용
  • 세마포어의 적용 (Signaling): 자원 관리뿐만 아니라, 스레드 간 실행 순서를 맞추는 신호기 역할을 할 때 사용

마지막 업데이트:

Operating System