반응형
ABA 문제란?
- 어떤 스레드가 변수의 값을 A라고 확인하고, 나중에 그 값이 여전히 A라서 안전하다고 착각해 연산을 진행했는데…
- 사실은 그 사이에 다른 스레드가 A → B → A로 바꿔치기한 경우 발생하는 문제.
- 즉, 값은 다시 A라서 “겉보기엔 변화 없음”처럼 보이지만, 실제로는 상태가 바뀌었고 의도하지 않은 결과가 생김.
Lock-Free Stack (스택 pop/push)
struct Node {
int data;
Node* next;
};
std::atomic<Node*> head;
- Thread T1 (Pop)
- head를 읽음 → Node A 가리킴
- A->next를 확인 → Node B
- CAS로 head를 A에서 B로 바꾸려 함
- Thread T2 (Pop+Push)
- T1이 CAS하기 전에 실행
- A를 pop → head는 B
- B도 pop → head는 C
- 다시 A를 push → head는 A
- T1 시점으로 돌아가서
- head는 여전히 A → CAS 성공
- 하지만 실제 head는 이미 A → pop → push 과정을 거친, 완전히 다른 상태
➡ 결과적으로 스택 구조가 꼬이거나, 이미 해제된 노드(A)에 접근하는 문제가 발생
Lock-Free Queue
- 큐의 head 포인터를 CAS로 업데이트할 때,
- 다른 스레드가 head 노드를 dequeue했다가 다시 recycle해서 enqueue → 다시 head에 등장
- CAS는 값이 여전히 동일하다고 판단 → 잘못된 링크 구조 발생
메모리 풀 / 오브젝트 재사용
- 메모리 관리에서 free list를 CAS 기반으로 업데이트할 때
- 이미 free된 노드가 다른 스레드에서 재할당 → 같은 주소지만 의미가 다른 객체가 됨
- CAS는 주소가 같으니 성공 → 잘못된 메모리 조작
왜 위험한가?
- CAS는 단순히 "값이 같은지 여부"만 확인하기 때문에, 값이 동일해도 그 사이의 변화를 감지하지 못함
- 결과적으로 메모리 안전성 문제(Use-after-free, Double-free)나 데이터 구조 불일치가 발생
반응형
'서버 개발 > 멀티쓰레드 프로그래밍' 카테고리의 다른 글
대표적인 락/동기화 도구 : Event, Semaphore, Condition Variable, Interlocked 함수, Spin Lock, Slim Tools (0) | 2025.09.18 |
---|---|
SRWLock / Critical Section / Mutex 장단점 비교 (0) | 2025.09.18 |
Epoch-based Reclamation (EBR, 시기 기반 메모리 회수) (0) | 2025.09.18 |
위험 포인터(Hazard Pointer) (0) | 2025.09.18 |