2025/09/18 5

ABA 문제와 사례

ABA 문제란?어떤 스레드가 변수의 값을 A라고 확인하고, 나중에 그 값이 여전히 A라서 안전하다고 착각해 연산을 진행했는데…사실은 그 사이에 다른 스레드가 A → B → A로 바꿔치기한 경우 발생하는 문제.즉, 값은 다시 A라서 “겉보기엔 변화 없음”처럼 보이지만, 실제로는 상태가 바뀌었고 의도하지 않은 결과가 생김. Lock-Free Stack (스택 pop/push)struct Node { int data; Node* next;};std::atomic head; Thread T1 (Pop)head를 읽음 → Node A 가리킴A->next를 확인 → Node BCAS로 head를 A에서 B로 바꾸려 함Thread T2 (Pop+Push)T1이 CAS하기 전에 실행A를 pop → head는..

대표적인 락/동기화 도구 : Event, Semaphore, Condition Variable, Interlocked 함수, Spin Lock, Slim Tools

Event (이벤트 객체)설명: 특정 조건이 충족될 때까지 스레드들을 대기시키거나, 시그널을 보내서 깨어나게 하는 도구.특징:CreateEvent, SetEvent, ResetEvent, WaitForSingleObject 등 사용Manual-reset / Auto-reset 방식 제공활용 예시:"리소스 로딩 끝날 때까지 기다려!" 같은 상황Producer-Consumer 패턴에서 유용Semaphore (세마포어)설명: 동시에 접근 가능한 스레드 개수를 제한하는 도구.특징:카운터 기반 → 0이면 대기, 양수면 접근 허용CreateSemaphore, ReleaseSemaphore 등 사용활용 예시:동시에 5개의 스레드만 DB 연결 풀을 사용할 수 있도록 제한Condition Variable (조건 변수)설..

SRWLock / Critical Section / Mutex 장단점 비교

SRWLOCK (Slim Reader/Writer Lock)장점가볍고 빠름: 유저 모드에서 동작, 커널 전환 최소화읽기/쓰기 모드 지원:여러 스레드가 동시에 읽기 가능 (Shared)쓰기는 한 스레드만 (Exclusive)조건 변수와 함께 사용 가능: SleepConditionVariableSRW 지원자동 초기화: 별도 Initialize 필요 없음 (구조체 초기화만으로 사용 가능)단점재진입 불가: 같은 스레드가 같은 락을 다시 획득하면 교착 상태 발생프로세스 내부 전용: 다른 프로세스와 공유 불가Windows Vista 이후에서만 지원 → 호환성 제한Mutex장점프로세스 간 동기화 가능: OS 커널 오브젝트 기반 → 여러 프로세스에서 공유 가능재진입 가능 (Reentrant): 같은 스레드가 여러 번 ..

Epoch-based Reclamation (EBR, 시기 기반 메모리 회수)

멀티스레드 환경에서 lock-free 자료구조를 쓰면, 메모리 해제가 큰 문제가 됩니다.어떤 스레드가 노드를 제거했다고 해도, 다른 스레드가 여전히 그 노드를 참조 중일 수 있습니다. 이때 free()를 즉시 해버리면, 참조 중인 스레드가 잘못된 메모리에 접근(Use-After-Free)해서 프로그램이 망가집니다.이를 해결하기 위해 EBR(Epoch-based Reclamation)은 모든 스레드가 특정 "안전 시점(Epoch)"을 지나야 메모리를 해제할 수 있도록 관리합니다. 시스템 전체에 Epoch(시기)라는 전역 카운터를 둡니다.각 스레드는 자신이 현재 어떤 Epoch에서 작업 중인지 기록합니다.메모리를 해제할 때 즉시 free하지 않고, “현재 Epoch에 묶어서” Retire List에 넣어둡니..

위험 포인터(Hazard Pointer)

Hazard Pointer(위험 포인터)는 Lock-free 자료구조에서 안전한 메모리 회수(memory reclamation)를 위해 고안된 기법입니다. 문제의 배경은 ABA 문제와 연결됩니다:어떤 스레드가 노드를 참조 중일 때, 다른 스레드가 그 노드를 해제하고 재활용하면, 첫 번째 스레드는 더 이상 유효하지 않은 메모리를 건드리게 됩니다(Use-After-Free).Hazard Pointer는 각 스레드가 내가 지금 참조하고 있는, 아직 해제되면 안 되는 노드의 주소를 표시하는 방식입니다.동작 방식각 스레드마다 Hazard Pointer 배열(혹은 슬롯)을 둡니다. 어떤 스레드가 lock-free 구조에서 노드를 읽을 때:노드 포인터를 읽기 전에 Hazard Pointer에 등록(= 보호 마킹).이..

반응형