운영체제Medium#196
Race Condition은 왜 발생하고 어떻게 예방할 수 있나요?
#운영체제#RaceCondition#동시성#Lock
답변 포인트
공유 상태와 임계 구역 보호를 기준으로 정의, 장점, 한계, 예시를 함께 설명해보세요.
정답 및 해설
빠른 요약
Race Condition은 여러 실행 흐름이 공유 데이터를 동시에 변경해 순서에 따라 결과가 달라지는 문제입니다. 락, 원자 연산, 불변 데이터, 메시지 패싱으로 줄일 수 있습니다.
Race Condition은 여러 실행 흐름이 공유 자원에 접근할 때 실행 순서에 따라 결과가 달라지는 문제입니다. 테스트에서는 잘 보이지 않다가 실제 부하나 특정 타이밍에서 데이터 손상, 중복 처리, 보안 취약점으로 나타날 수 있습니다.
핵심 개념
- 읽기-수정-쓰기(read-modify-write)가 원자적으로 처리되지 않으면 경쟁이 생깁니다.
- 공유 상태와 비결정적 스케줄링이 결합될 때 발생합니다.
- 예방 방법은 공유 상태를 줄이거나, 접근을 동기화하거나, 원자적 연산/트랜잭션을 사용하는 것입니다.
동작 방식 또는 판단 기준
이 주제를 이해할 때는 다음 순서로 보면 실무 적용이 쉬워집니다.
- 무엇을 해결하려는가: 성능, 표현력, 안정성, 접근성 중 어떤 문제를 줄이려는지 확인합니다.
- 전제 조건은 무엇인가: 정렬 여부, 브라우저 지원, 네트워크 특성, 동시성 조건처럼 성립해야 하는 조건을 점검합니다.
- 비용은 어디서 발생하는가: 시간 복잡도, 메모리, 캐시, 재시도, 렌더링 비용처럼 병목 지점을 나눠 봅니다.
- 실패 시 어떤 문제가 생기는가: 잘못 적용했을 때의 버그나 운영 리스크를 함께 고려합니다.
실제 예시
JavaScript
// 개념 예: 동시에 실행되면 둘 다 같은 잔액을 읽을 수 있음
async function withdraw(accountId, amount) {
const account = await db.accounts.find(accountId);
if (account.balance < amount) throw new Error('insufficient');
await db.accounts.update(accountId, { balance: account.balance - amount });
}SQL
-- 더 안전한 방식: 조건부 원자 업데이트
UPDATE accounts
SET balance = balance - 100
WHERE id = 1 AND balance >= 100;실무에서 주의할 점
- JavaScript처럼 단일 스레드 이벤트 루프를 쓰더라도 비동기 작업 사이에서는 race condition이 발생할 수 있습니다.
- lock을 추가하면 race는 줄지만 deadlock이나 성능 저하를 만들 수 있습니다.
- 캐시, 메시지 큐, DB replica까지 포함하면 경쟁 범위가 애플리케이션 메모리를 넘어섭니다.
실무 적용 가이드
- DB 트랜잭션, optimistic/pessimistic locking, unique constraint를 적극 활용합니다.
- idempotency key로 중복 요청을 안전하게 처리합니다.
- 공유 mutable state를 줄이고 immutable message passing 구조를 선호합니다.
함께 연결해서 보면 좋은 키워드
Race Condition, Concurrency, Lock, Transaction, Atomicity
정리
Race Condition은 여러 실행 흐름이 공유 자원에 접근할 때 실행 순서에 따라 결과가 달라지는 문제입니다. 다만 개념 자체보다 중요한 것은 적용 조건과 한계를 함께 이해하는 것입니다. 작은 예제에서는 단순해 보여도 실제 서비스에서는 성능, 보안, 유지보수성, 접근성 요구사항이 함께 얽히므로, 문제의 성격을 먼저 파악한 뒤 적절한 도구로 선택하는 것이 좋습니다.