Skip to content

[OS] Race Condition

공유 자원에 여러 실행 흐름이 동시에 접근할 때, 실행 순서에 따라 결과가 달라지는 상태를 말한다.

동시 접근 시 자료의 일관성이 깨질 수 있다.


Race Condition이 발생하는 경우

  1. 인터럽트 컨텍스트와 일반 커널 컨텍스트가 같은 데이터를 건드릴 때
    • 문제점: 일반 커널 코드가 공유 데이터를 수정하는 도중 인터럽트 핸들러가 같은 데이터를 건드릴 수 있다.
    • 해결법: 아주 짧은 구간에서는 로컬 인터럽트를 막거나, 보통은 irqsave 계열 스핀락처럼 인터럽트 안전한 락을 사용한다.
  2. 커널 코드가 선점(preemption)되거나 다른 커널 스레드와 경쟁할 때
    • 문제점: 현대 커널은 커널 모드라고 해서 항상 "절대 문맥 교환되지 않는다"는 보장이 없다. 선점형 커널에서는 같은 공유 상태를 두 실행 흐름이 번갈아 만질 수 있다.
    • 해결법: 뮤텍스, 스핀락, 원자 연산, refcount, seqlock 등 상황에 맞는 동기화 기법으로 보호한다.
  3. 멀티코어/멀티프로세서 환경에서 같은 공유 메모리를 접근할 때
    • 문제점: 서로 다른 CPU가 동시에 같은 데이터를 읽고 쓰면 단일 CPU보다 더 쉽게 race condition이 발생한다.
    • 해결법: 락뿐 아니라 메모리 순서(memory ordering) 까지 고려한 동기화가 필요하다.
  4. 사용자 공간의 멀티스레드 프로그램에서 공유 데이터를 접근할 때
    • 문제점: 전역 변수, 힙 객체, 큐 등을 여러 스레드가 동시에 수정하면 잘못된 결과가 나온다.
    • 해결법: 뮤텍스, 조건 변수, 세마포어, 원자 연산 같은 사용자 공간 동기화 도구를 사용한다.

핵심 정리

  • race condition은 "여러 주체가 동시에 접근한다"는 사실 자체보다, 그 접근 순서에 따라 결과가 달라진다는 점이 핵심이다.
  • 커널 모드라고 해서 자동으로 안전하지 않다.
  • 단일 CPU에서도 인터럽트와 선점 때문에 race condition은 발생할 수 있다.
  • 멀티코어에서는 락과 함께 메모리 가시성까지 고려해야 한다.