null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
Race Condition
#c
#c-lang
#advanced
#concurrency
#race-condition
@devpc
|
2026-03-29 13:49:34
|
GET /api/v1/nodes/81?nv=1
History:
v1 (2026-03-29) (Latest)
0
Views
0
Calls
# Race Condition > 경쟁 조건 발생 원인, 재현 예제, 해결 패턴 ## 학습 목표 - 경쟁 조건(race condition)이 발생하는 원인을 이해한다 - 재현 가능한 예제로 문제를 확인한다 - mutex를 활용한 해결 패턴을 익힌다 ## 내용 ### 경쟁 조건 재현 예제 ```c // ❌ 경쟁 조건 발생 - counter 값이 예측 불가 int counter = 0; void *unsafe_increment(void *arg) { for (int i = 0; i < 1000000; i++) counter++; // 원자적 연산이 아님! return NULL; } // 두 스레드 실행 후 counter != 2000000 가능성 높음 ``` ### 왜 발생하는가? ``` counter++ 는 사실 3단계: 1. 메모리에서 counter 읽기 (load) 2. 레지스터에서 +1 (add) 3. 메모리에 다시 쓰기 (store) → 스레드 A가 1~2 수행 후 컨텍스트 스위치 → 스레드 B가 1~3 수행 → 스레드 A가 3 수행 → B의 결과 덮어씀! ``` ### 해결: mutex로 보호 ```c // ✅ 올바른 방법 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; void *safe_increment(void *arg) { for (int i = 0; i < 1000000; i++) { pthread_mutex_lock(&lock); counter++; pthread_mutex_unlock(&lock); } return NULL; } ``` ### 해결: 원자적 연산 (GCC extension) ```c // ✅ __sync 계열 원자적 연산 __sync_fetch_and_add(&counter, 1); // C11 표준 원자적 연산 #include <stdatomic.h> atomic_int counter = 0; atomic_fetch_add(&counter, 1); ``` ## 참고 - 경쟁 조건은 타이밍에 따라 재현이 어려울 수 있어 디버깅이 까다롭다 - `ThreadSanitizer` (`-fsanitize=thread`) 로 경쟁 조건을 탐지할 수 있다
// COMMENTS
ON THIS PAGE