Files
2nd/10_Wiki/Topic_Programming/Coding/CS_Lock_Free_Patterns.md
T
Antigravity Agent 9148c358d0 docs(10_Wiki): 위키 전체 재구성 — Topic_* 폴더를 4개 카테고리로 통합 + 대규모 중복 제거
Topic_Agent/Topic_Blog/Topics/Topics_Biz/Topics_Meeting/Topics_Rag의 마크다운 지식 문서를
Topic_General/Topic_Programming/Topic_Graphic/Topic_Business 4개 카테고리로 재분류.

- 중복 제거: frontmatter의 status:duplicate/merged + duplicate_of/redirect_to 필드로
  자기 자신을 중복으로 선언한 리다이렉트 stub 1032개 제거, 완전 동일 내용 파일 472개 제거,
  동일 파일명·다른 내용 충돌 시 더 큰(완전한) 버전만 유지(162개 제거) — 총 1639개 중복 제거.
- 분류: 폴더 단위로 명확한 항목(AI_and_ML/Coding/Architecture 등 → Programming,
  Comfyui/Visual_Effects → Graphic, Topics_Biz/Topics_Meeting/사업 등 → Business,
  Poetic_Blog_Writing/창의성/Game_Design 등 → General)은 폴더 우선순위로,
  나머지 혼재 폴더(Topic_Agent/Topic_Blog/Topics 루트/Thinking & Reasoning/Other/UI_UX_Assets)는
  title/tags 키워드 스코어링으로 파일 단위 분류(불명확한 경우 General로 폴백).
  원본 폴더명은 "From_*" 서브폴더로 보존해 추적 가능성 유지.
- 최종 배치: Programming 2784 / General 1608 / Graphic 285 / Business 249 = 4926개 문서.
- 에이전트 운영 상태(.astra/.agent/.obsidian/sessions/memory/_company/docs/lessons/_shared/src)는
  지식 콘텐츠가 아니므로 재분류 대상에서 제외하고 원위치 유지.
- Topics/Topic_email(상위 보호 폴더 Topic_email과 파일명 100% 중복) 삭제 — 보호 폴더 자체는 미변경.
- 완전히 비게 된 Topic_Agent/Topic_Blog/Topics_Biz/Topics_Rag 폴더 제거.
2026-07-05 00:33:48 +09:00

7.2 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
cs-lock-free-patterns Lock-Free Patterns — atomic / CAS / queue Coding draft B conceptual 2026-05-09 2026-05-09
cs
concurrency
vibe-coding
language applicable_to
C++ / Rust
CS
Backend
lock-free
wait-free
CAS
compare and swap
atomic
MPSC
MPMC
ABA problem

Lock-Free Patterns

Lock = 느린, deadlock 위험. Atomic + CAS = lock-free. Wait-free 가 강함.

📖 핵심 개념

  • Atomic: 원자 operation.
  • CAS: Compare-And-Swap.
  • Lock-free: 1+ thread 가 progress.
  • Wait-free: 매 thread 가 progress.

💻 코드 패턴

Atomic counter

use std::sync::atomic::{AtomicU64, Ordering};

let counter = AtomicU64::new(0);

// Thread-safe
counter.fetch_add(1, Ordering::SeqCst);

let val = counter.load(Ordering::SeqCst);

CAS (Compare-And-Swap)

let atomic = AtomicU64::new(0);

loop {
    let old = atomic.load(Ordering::SeqCst);
    let new = old + 1;
    if atomic.compare_exchange(old, new, Ordering::SeqCst, Ordering::SeqCst).is_ok() {
        break;
    }
    // 다른 thread 가 변경. Retry.
}

→ "if 같으면 set". Atomic.

Memory order

Relaxed: 매 thread 의 자체 ordering 만.
Acquire / Release: 인접 op 의 ordering.
SeqCst: total ordering (제일 안전, 느린).

TS / JavaScript SharedArrayBuffer

const sab = new SharedArrayBuffer(8);
const view = new Int32Array(sab);

// Atomic
Atomics.add(view, 0, 1);
Atomics.compareExchange(view, 0, oldVal, newVal);
Atomics.wait(view, 0, 0);
Atomics.notify(view, 0);

→ Worker 간 shared.

Lock-free queue (Michael-Scott)

struct Node<T> {
    value: T,
    next: AtomicPtr<Node<T>>,
}

struct Queue<T> {
    head: AtomicPtr<Node<T>>,
    tail: AtomicPtr<Node<T>>,
}

impl<T> Queue<T> {
    fn enqueue(&self, value: T) {
        let new_node = Box::into_raw(Box::new(Node { value, next: AtomicPtr::new(null_mut()) }));
        
        loop {
            let tail = self.tail.load(SeqCst);
            let next = unsafe { (*tail).next.load(SeqCst) };
            
            if next.is_null() {
                if unsafe { (*tail).next.compare_exchange(null_mut(), new_node, SeqCst, SeqCst) }.is_ok() {
                    self.tail.compare_exchange(tail, new_node, SeqCst, SeqCst).ok();
                    return;
                }
            } else {
                self.tail.compare_exchange(tail, next, SeqCst, SeqCst).ok();
            }
        }
    }
}

→ Multi-producer multi-consumer.

MPSC (single consumer)

// Crossbeam (Rust)
use crossbeam::channel::unbounded;

let (tx, rx) = unbounded();

// Multiple producer
thread::spawn(move || tx.send(1).unwrap());

// Single consumer
let v = rx.recv().unwrap();

→ Lock-free queue.

Crossbeam (Rust)

- Unbounded / bounded channel.
- ArrayQueue / SegQueue.
- AtomicCell.
- Epoch-based GC.

ABA problem

Thread A:
- Load X = 1.
Thread B:
- Set X = 2.
- Set X = 1.
Thread A:
- CAS X (expect 1) = success.
- → wrong (X 가 변경 됐는데 안 알아).
// Solution: tagged pointer (counter + value).
let old: (u64, T) = atomic.load();   // counter + value
let new = (old.0 + 1, new_value);
atomic.compare_exchange(old, new, ...);

→ Counter 가 increment. 같은 value 가 다른 counter.

Memory reclamation

Lock-free 의 함정:
- Free 한 node 의 다른 thread 가 still 참조.

Solution:
- Hazard pointer.
- Epoch-based GC (crossbeam).
- RCU (Read-Copy-Update).

Lock-free hash map

DashMap (Rust):
- Sharded (16 partition).
- 매 partition 의 Lock-free or fine lock.
- 큰 throughput.
use dashmap::DashMap;
let map: DashMap<String, u32> = DashMap::new();

map.insert("key".into(), 42);
let v = map.get("key");

Atomic reference counting (Rust Arc)

use std::sync::Arc;
use std::sync::atomic::AtomicUsize;

let arc = Arc::new(MyData);
let arc2 = arc.clone();   // count++

// Drop = count--. 0 = free.

Java AtomicInteger / AtomicReference

AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet();

AtomicReference<Node> head = new AtomicReference<>();
head.compareAndSet(expected, newValue);

Go (sync/atomic)

import "sync/atomic"

var counter int64
atomic.AddInt64(&counter, 1)

old := atomic.LoadInt64(&counter)
atomic.CompareAndSwapInt64(&counter, old, old + 1)

Wait-free

Lock-free: 1+ thread 가 progress.
Wait-free: 매 thread 가 progress.

Wait-free = stronger. 보통 lock-free 가 충분.

Software Transactional Memory (STM)

-- Haskell
atomically $ do
  x <- readTVar var
  writeTVar var (x + 1)
;; Clojure
(dosync
  (alter counter inc))

→ Optimistic concurrency. Conflict 시 retry.

Use case

- Counter (statistics).
- Single producer queue (logging).
- Lock-free hash (cache).
- Reference count (shared ownership).
- LSM tree memtable.
- WAL (write-ahead log).

vs Mutex

Mutex:
- Simple.
- Block 가능 (sleep).
- Deadlock 위험.

Lock-free:
- Complex.
- Non-blocking.
- 더 빠름 (high contention).
- 더 어려움.

→ 작은 critical section = mutex.
큰 contention = lock-free.

Lock contention 측정

perf record / perf report.
- Hot mutex 발견.
- Lock-free 의 candidate.

→ Profile 가 답.

Lock-free의 함정

- ABA problem: tagged pointer.
- Memory reclamation: hazard pointer / epoch.
- Memory ordering: SeqCst 가 안전 default.
- Algorithm 가 매우 어려움.
- Test 어려움 (race rare).

→ Library (Crossbeam / Folly) 사용. 자체 X.

Folly (Facebook C++)

#include <folly/MPMCQueue.h>
folly::MPMCQueue<int> queue(1024);
queue.write(42);
int x;
queue.read(x);

LMAX Disruptor (Java)

RingBuffer<Event> ringBuffer = ...;

long sequence = ringBuffer.next();
Event event = ringBuffer.get(sequence);
event.setValue(42);
ringBuffer.publish(sequence);

→ 매우 빠른 (millions / sec).

Database 의 lock-free

MVCC: lock-free read.
LSM tree: lock-free memtable insert.
B-tree (some): lock-free split.

→ Modern DB 의 핵심.

When use?

✓ High contention.
✓ Real-time (no block).
✓ Embedded / kernel.

✗ Low contention (mutex 충분).
✗ Logic 가 복잡.
✗ Team 가 expert X.

→ Profile 후. Library 사용.

Real-world

  • Crossbeam (Rust).
  • Folly (C++ Facebook).
  • DashMap (Rust hash).
  • LMAX Disruptor (Java).
  • Java concurrent.atomic.

🤔 의사결정 기준

작업 추천
Counter Atomic
Queue Lock-free queue (Crossbeam)
Hash map DashMap / ConcurrentHashMap
Ref count Arc / shared_ptr
큰 throughput LMAX Disruptor
Database MVCC + LSM
Complex sync STM (Haskell / Clojure)

안티패턴

  • 자체 lock-free queue: bug.
  • No memory order: race.
  • No ABA fix: corruption.
  • No memory reclamation: leak / use-after-free.
  • Mutex on hot path: contention.

🤖 LLM 활용 힌트

  • Library 사용 (자체 X).
  • ABA + memory reclamation 가 큰 함정.
  • Profile + measure.
  • MVCC + LSM 가 DB 의 lock-free.

🔗 관련 문서