41. Interlocked.CompareExchange 기반 락프리 갱신과 ABA
난이도 상 해설 보기 →
결함을 모두 찾고 원인·수정안·더 나은 설계를 제시하라. 마커
(A)(B) 는 주목 위치 힌트다.
결함 코드 · C#
// [주제] Interlocked.CompareExchange 기반 락프리 갱신의 내부 동작과 ABA
//
// 게임서버에서 락 경합을 줄이려 CAS(Compare-And-Swap) 루프로 무잠금 갱신을
// 구현했다. 아래 코드의 동작과 내부 동작을 예측·설명하라.
//
// [과제]
// 1) UpdatePeak 의 CAS 루프가 어떻게 "조건부 최댓값 갱신"을 잠금 없이
// 원자적으로 수행하는지, 루프가 왜 필요한지(경합 시 재시도) 설명하라.
// Interlocked.CompareExchange 의 반환값은 무엇이며 성공/실패를 어떻게 판정하나?
// 2) Interlocked 연산이 제공하는 메모리 순서 보장(가시성/재정렬)은 무엇인가?
// volatile 읽기만으로 이 갱신을 대체할 수 없는 이유는?
// 3) Pop 의 CAS 루프에는 ABA 문제가 있다. 어떤 인터리빙에서 노드 하나가
// "그대로인 것처럼" 보여 잘못된 head 가 설정되는지 재현 시나리오로 설명하라.
// 4) "락프리"와 "대기없음(wait-free)"의 차이, 그리고 이 코드가 어느 쪽인지 논하라.
using System.Threading;
public class LockFreeStats
{
private long _peak;
public void UpdatePeak(long candidate)
{
long observed;
do
{
observed = Interlocked.Read(ref _peak);
if (candidate <= observed) return; // 갱신 불필요
}
while (Interlocked.CompareExchange(ref _peak, candidate, observed) != observed);
}
}
public class LockFreeStack<T>
{
private class Node { public T Value; public Node Next; }
private Node _head;
public void Push(T value)
{
var n = new Node { Value = value };
Node old;
do
{
old = _head;
n.Next = old;
}
while (Interlocked.CompareExchange(ref _head, n, old) != old);
}
public bool Pop(out T value)
{
Node old;
do
{
old = _head;
if (old == null) { value = default; return false; }
}
while (Interlocked.CompareExchange(ref _head, old.Next, old) != old);
value = old.Value;
return true;
}
} 내 리뷰 · C#
내 답안 · 자동 저장
작성 후 위 해설 보기에서 모범 해설과 대조하세요.