동시성과 병렬성에대해 CS공부하다가
동시성에서 자주 나오는 Race condition을 다루면 좋을거같아서 오늘은
여러가지 주제로 얘기해볼까 한다.
Race condition은 컴퓨터 공학 책을 공부하면 꼭 나오는 키워드이다
저도 컴퓨터 공학 기초 관련 서적을 읽으면서 한 번 이상은 접했었다
어느정도 이해했다고 자기 최면에 빠진 상태로 넘어갔었는데,
단순한 정의만 이해하고 있다는 것을 알게되었다.
Race condition이란?
둘 이상의 입력 또는 조작의 타이밍이나 순서 등이 결과값에 영향을 줄 수 있는 상태
Race condition은 공유(공통) 자원을 둘 이상의 스레드 혹은 프로세스가 읽거나 쓰면서
결과값이 의도와 달라질 수 있는 문제다

int sharedNumber = 0;
//스레드 1
sharedNumber += 1;
// 스레드 2
sharedNumber += 1;
위 예시에서 스레드 1과 스레드 2는 동시에 shardNumber를 읽고 수정하려고 시도할 수 있다.
스레드 1, 스레드 2 모두 0으로 초기화된 sharedNumber에 1을 초기화 하려 하지만, 선행된 스레드의 작업으로 인해
순서가 보장되지 않아, 의도치 않은 결과 값이 나올 수 있다.
Race condition의 문제점
- 예측 불가능한 결과
- 여러 스레드나 프로세스마다 실행 속도가 달라서 잘못된 값을 읽거나 수정할 수 있다.
- A스레드가 수정 한 결과를 B가 수정하면서 A가 수정한 결과는 없어지게 된다.
- 일관성 손실
- 여러 스레드나 프로세스가 데이터를 수정 시 예기치 않은 상태로 데이터가 변경될 수 있다.
- 디버깅의 어려움
- 여러 스레드나 프로세스의 각각 다른 실행 속도로 인해 실행 흐름을 읽기 힘들어 디버깅이 힘듬
- 잠금 대기 시간
- Race condition을 방지하기 위해 무분별한 락(Lock)을 사용할 시, 대기 시간으로 인해 성능 저하가 발생할 수 있다
Race condition을 예방하는 방법
- 상호 배제(Mutual Exclusion)
- 공유 데이터에 접근하는 부분을 임계 영역(Critical Section)으로 지정하고, 한 번에 하나의 실행 흐름만 해당 영역에 들어가도록 한다.
- 공유 데이터를 최소화한 병렬 처리 설계
- 데이터를 적절히 분리하여 각 스레드가 독립적으로 처리하도록 한다
- 스레드 안전성 보장(Thread Safe)
- 공유 데이터를 수정하는 함수나 메서드를 스레드 안전하도록 구현
- 이를 위해 스레드 동기화 기법을 사용하거나 불변 객체(Immutable Object)패턴 적용
- 테스트와 검증
- 코드를 작성 후 테스트를 진행합니다.
- 테스트 코드를 작성해서 원하는 결과가 나오는지 확인한다.
상호 배제(Mutual Exclusion, Mutex)

동시 프로그래밍에서 공유 불가능한 자원의 동시 사용을 피하기 위해 사용되는
알고리즘으로, 임계 구역(critical section)으로 불리는 코드 영역에 의해 구현된다.
- 공유된 자원의 데이터를 여러 스레드가 접근하는 것을 막는 방법
- 공유된 자원은 한 번에 한 프로세스(스레드)만이 사용할 수 있어야 한다.
- key에 해당하는 어떤 오브젝트가 있으며 이 오브젝트를 소유한 쓰레드, 프로세스 만이 공유자원에 접근할 수 있다.
흔히 뮤텍스는 키(열쇠)가 하나뿐인 화장실을 예로 들어서 설명한다.
화장실을 이용하기 위해서는 열쇠를 카운터에서 받아 가야 하고,
누군가 화장실 키를 가지고 사용하고 있으면 다른 사람들은 카운터에서 기다려야 한다.
화장실을 이용하는 사람은 프로세스 혹은 스레드이며 화장실은 공유자원,
화장실 키는 공유자원에 접근하기 위해 필요한 어떤 오브젝트이다.
상호 배제에 대해서는 어느정도 이해를 했었다
임계 구역이라는 것은 무엇을 의미하는지 궁금해서 찾아봤다.
임계 구역(Critical Section)이란?
공유변수 영역은 병렬컴퓨팅에서 둘 이상의 스레드가 동시에 접근해서 안되는 공유 자원
(자료 구조 또는 장치)을 접근하는 코드의 일부를 말한다.
간단하게 정리하면 병렬 컴퓨팅과 멀티스레드 프로그래밍에서 상호 배제를 적용하는 부분을 가리키는 용어다
임계 구를 효과적으로 사용하는 것은 Race condition과 같은 동시성 문제를 해결하기 위해 중요하다.
이런 임계 구역에 접근하기 전에 락(Lock)이나 세마포어(Semaphore)와 같은 동기화 메커니즘을 사용하여
한 번에 하나의 실행 흐름만이 임계구역에 들어갈 수 있도록 합니다.
임계 구역을 제대로 알고 Race condition을 예방하면,
데이터의 일관성과 안전한 동시성 프로그래밍을 보장하는데 중요한 역할을 한다.
교착 상태(DeadLock) 이란?
교착 상태란 두 개 이상의 프로세스 또는 스레드가 서로가 가진 자원을 얻기 위해 무한히 기다리는 상태를 의미한다.
일반적으로 교착상태는 네 가지 조건이 동시에 충족될 때 발생한다.
- 상호 배제(Mutual Exclusion)
- 공유 데이터에 접근하는 부분을 임계 영역(Critical Section)으로 지정하고, 한 번에 하나의 실행 흐름만 해당 영역에 들어가도록 한다.
- 점유 대기 (Hold and Wait) :
- 프로세스가 이미 어떤 자원을 가지고 있으면서 다른 자원을 기다린다.
- 비선점 (No Preemption)
- 자원은 다른 프로세스에 의해 강제로 뺏길 수 없어야 한다.
- 순환 대기(Circular Wait)
- 프로세스의 그룹에서 순환 대기 관계가 형성되어야 한다. 즉 각 프로세스는 다음 프로세스가 점유한 자원을 대기하고 있어야 한다.
교착 상태를 피하는 방법
실무에서 교착상태 이슈는 생각보다 빈번히 일어나며, 교착 상태가 발생하면 프로그램이 무한히 멈춰버리며,
장애상황으로 이어지기때문에 선제적인 예방이 중요하다.
- 자원 해제
- 프로세스가 필요한 모든 자원을 한 번에 요청하도록 변경하고, 모든 자원을 점유한 후에 요청을 해제하도록 하는 방법을 사용한다.
- 타임아웃과 롤백
- 일정 시간 동안 자원을 얻지 못하면 프로세스가 해당 자원을 해제하고 다른 작업을 수행하도록 하는 방법을 사용한다.
- ex:) 일정시간 이상 자원을 얻지 못할 경우 기존 작업된 내용을 모두 롤백하여 요청을 무효화 시킨다.
- 자원 할당 그래프
- 교착 상태를 감지하기 위한 그래프 모델을 사용하여 프로세스와 자원 간의 관계를 모니터링한다.
보통 교착 상태는 운영 체제, 데이터베이스, 네트워크 시스템에서 발생하는데, 이러한 시스템에서 교착 상태를 피하기 위해 복잡한 알고리즘이 사용된다.
'CS' 카테고리의 다른 글
| [CS] - MVCC(다중 버전 동시성 제어) (0) | 2025.12.30 |
|---|---|
| [CS] - 트랜잭션(Transaction),ACID, 트랜잭션 격리 수준(Isolation Level) (0) | 2025.12.30 |
| [CS] - 동시성(Concurrency) VS 병렬성(Parallelism) (0) | 2025.12.28 |
| [CS] - 운영체제의 CPU 스케줄링 (0) | 2025.12.27 |
| [CS] - 프로세스와 스레드의 차이 (0) | 2025.12.27 |