К основному содержанию
скилл CX Codex

memory-model — скилл для Claude Code: порядок памяти в C++ и Rust

Скилл для работы с моделью памяти C++ и Rust: подсказывает, какой memory order выбрать, и разбирает гонки данных в атомиках.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add mohitmishra786/low-level-dev-skills --skill memory-model -a claude-code
Открыть на GitHub

Что делает memory-model

Скилл включается, когда в разговоре всплывают memory ordering, acquire-release, seq_cst, relaxed-атомики, happens-before, барьеры памяти, std::atomic или Rust-атомики. Агент получает таблицу соответствия между C++ и Rust, шкалу силы ордеров от Relaxed до SeqCst и разбор того, что каждый ордер гарантирует.

Внутри — рабочий процесс из восьми шагов: обзор ордеров, таблица memory_order_* против Ordering::*, примеры на std::atomic, дерево выбора ордера под задачу, готовые паттерны (спинлок, подсчёт ссылок, ленивая инициализация), Rust-атомики, барьеры и таблица частых ошибок. Отдельно разобрано, почему volatile в C++ не годится для потокобезопасности и почему SeqCst везде — не лучший вариант.

Скилл ссылается на справочник references/cpp-memory-ordering.md и на смежные скиллы: санитайзеры для поиска гонок, Miri для проверки нарушений порядка в Rust, ассемблер x86 для разбора сгенерированных инструкций-барьеров. Ставить его стоит, если вы пишете lock-free структуры или разбираете чужой конкурентный код — на глаз такие ошибки не ловятся.

Какие задачи решает

  • выбрать memory order под конкретную атомарную операцию
  • разобрать, почему acquire-release не даёт нужной синхронизации
  • собрать lock-free очередь с несколькими производителями
  • найти гонку данных в коде на std::atomic
  • перевести паттерн с C++ атомиков на Rust Ordering

Примеры запросов агенту

  • Какой memory order поставить на этот store, если я публикую данные в другой поток?
  • Помоги разобрать спинлок на std::atomic_flag — правильные ли там acquire и release
  • Перепиши этот счётчик ссылок с C++ на Rust-атомики, объясни выбор Ordering

Как установить memory-model

1Через Skills CLI (Vercel)

npx skills add mohitmishra786/low-level-dev-skills --skill memory-model -a claude-code

2Вручную: положить файлы

~/.claude/skills/memory-model/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/memory-model/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора62

lldb Подсказывает команды LLDB для отладки C, C++, Swift и Objective-C. Пригодится при переходе с GDB или настройке отладки в macOS и VS Code. CX Codex +1 646установок simd-intrinsics Скилл ведёт агента через ручную векторизацию: чтение отчётов авто-векторизации, интринсики SSE2/AVX2/NEON и проверка флагов CPU в рантайме. CX Codex +1 645установок elf-inspection Ведёт агента по readelf, objdump, nm и ldd: зависимости, символы, секции, отладочная информация и ошибки линковки. CX Codex +1 640установок linux-kernel-modules Ведёт агента по написанию и отладке загружаемых модулей ядра Linux: Kbuild, параметры модуля, /proc, sysfs, символьные устройства, KGDB и ftrace. CX Codex +1 639установок heaptrack Ведёт агента по heaptrack: запись трасс аллокаций, разбор через heaptrack_print, поиск утечек и сравнение запусков. CX Codex +1 623установок msvc-cl Подсказывает агенту, как компилировать C и C++ через MSVC cl.exe и clang-cl: флаги, рантайм, PDB, ошибки линковки. CX Codex +1 617установок linkers-lto Скилл для настройки линкеров GNU ld, gold и lld, разбора ошибок порядка библиотек и включения LTO в реальных проектах. CX Codex +1 608установок binutils Скилл для работы с бинарниками: статические библиотеки, strip, objcopy, addr2line, strings и c++filt. Пригодится, когда агент должен сам разобраться с постобработкой ELF. CX Codex +1 608установок

Похожие

memory-safety-patterns Seth Hobson Скилл помогает писать код на Rust, C++ и C с учётом владения памятью, RAII и управления ресурсами. Подойдёт для системного кода и поиска ошибок памяти. CX Codex 11 746установок rust-async-patterns Seth Hobson Скилл помогает писать и разбирать асинхронный Rust на Tokio: задачи, каналы, потоки и обработку ошибок. Пригодится для сетевых сервисов и отладки. CX Codex 20 625установок rust-patterns affaan-m Задаёт правила идиоматичного Rust: управление владением, типизированные ошибки, сопоставление с образцом и трейты. Пригодится при написании, рефакторинге и ревью Rust-кода. CX Codex +1 5 100установок m07-concurrency actionbook Помогает разбирать конкурентный и асинхронный Rust-код: выбрать потоки, async/await, каналы или синхронизацию. Нужен при ошибках Send/Sync, дедлоках и гонках. CX Codex +1 3 500установок cpp-pro VoltAgent Community Субагент для системной разработки на C++20/23 с упором на производительность, шаблонное метапрограммирование и проверки санитайзерами. 781установок rust-systems-programming manutej Скилл по системному Rust: владение, заимствование, потоки, async, unsafe и оптимизация. Пригодится, когда пишешь низкоуровневый код или переписываешь C/C++. CX Codex +1 485установок

Рядом в теме «Языки программирования»

Все скиллы по теме «Языки программирования» →

Вопросы о memory-model

Как установить memory-model в Claude?

Одной командой: npx skills add mohitmishra786/low-level-dev-skills --skill memory-model -a claude-code. После неё скилл лежит в ~/.claude/skills/memory-model/SKILL.md.

Что делает memory-model?

Ведёт агента по модели памяти C++ и Rust: объясняет ордера, отношение happens-before, барьеры и паттерны lock-free структур. Активируется на вопросах про std::atomic, acquire-release, seq_cst и relaxed-атомики.

С какими скиллами он работает вместе?

С санитайзерами для отлова гонок, с Miri для проверки нарушений порядка в Rust и с ассемблером x86, если нужно посмотреть сгенерированные инструкции-барьеры.

Исходный текст

SKILL.md · MIT
---
name: memory-model
description: C++ and Rust memory model skill for concurrent programming. Use when understanding memory ordering, writing lock-free data structures, using std::atomic or Rust atomics, diagnosing data races, or selecting the correct memory order for atomic operations. Activates on queries about memory ordering, acquire-release, seq_cst, relaxed atomics, happens-before, memory barriers, std::atomic, or Rust atomic ordering.
---

# Memory Model

## Purpose

Guide agents through C++ and Rust memory models: memory orderings, the happens-before relation, atomic operations, fences, and practical patterns for lock-free data structures.

## Triggers

- "What is the C++ memory model?"
- "What memory order should I use for my atomic operation?"
- "What is the difference between acquire-release and seq_cst?"
- "How do I use std::atomic in C++?"
- "What is acquire/release in Rust atomics?"
- "How do I implement a lock-free queue?"

## Workflow

### 1. Memory ordering overview

Modern CPUs and compilers reorder operations for performance. The memory model specifies what reorderings are allowed and how synchronisation is achieved.

```text
Ordering strength (weakest to strongest):
Relaxed < Release/Acquire < AcqRel < SeqCst

Stronger ordering = more synchronization = more correct, but slower
Weaker ordering  = fewer barriers = faster, but needs careful analysis
```

### 2. Memory orderings

| Order | C++ | Rust | What it means |
|-------|-----|------|--------------|
| Relaxed | `memory_order_relaxed` | `Ordering::Relaxed` | No ordering guarantee; just atomicity |
| Consume | `memory_order_consume` | (use Acquire) | Data dependency ordering |
| Acquire | `memory_order_acquire` | `Ordering::Acquire` | This load sees all writes before the matching release |
| Release | `memory_order_release` | `Ordering::Release` | All writes before this store are visible to acquire |
| AcqRel | `memory_order_acq_rel` | `Ordering::AcqRel` | Both acquire and release on RMW ops |
| SeqCst | `memory_order_seq_cst` | `Ordering::SeqCst` | Total order across all seq_cst operations |

### 3. C++ std::atomic

```cpp
#include <atomic>
#include <thread>

std::atomic<int> counter{0};
std::atomic<bool> ready{false};

// Producer thread
void producer() {
    data = 42;                              // (1) write data
    ready.store(true, std::memory_order_release);  // (2) signal
}

// Consumer thread
void consumer() {
    while (!ready.load(std::memory_order_acquire));  // (3) wait
    assert(data == 42);                              // (4) guaranteed to see (1)
}
```

Acquire-release guarantees: if thread A does a **release store** to X, and thread B does an **acquire load** that sees A's value, then all writes by A before the release are visible to B after the acquire.

### 4. Choosing the right ordering

```text
Use case?
├── Counter (just needs atomicity, order irrelevant)    → Relaxed
├── Reference counting (decrement + final check)        → AcqRel (dec), Acquire (load 0 check)
├── Publish data from one thread to another             → Release (store), Acquire (load)
├── Mutual exclusion / mutex implementation             → AcqRel / SeqCst
├── Lock-free queue multiple producers/consumers        → SeqCst (safest to start)
└── Sequence number check (simple flag)                 → Release + Acquire
```

### 5. Common patterns

```cpp
// Pattern 1: Spinlock
class Spinlock {
    std::atomic_flag flag = ATOMIC_FLAG_INIT;
public:
    void lock() {
        while (flag.test_and_set(std::memory_order_acquire))
            ; // spin
    }
    void unlock() {
        flag.clear(std::memory_order_release);
    }
};

// Pattern 2: Reference counting
class RefCounted {
    std::atomic<int> refcount{1};
public:
    void addref() {
        refcount.fetch_add(1, std::memory_order_relaxed);  // only need atomicity
    }
    void release() {
        if (refcount.fetch_sub(1, std::memory_order_acq_rel) == 1) {
            // AcqRel ensures we see all writes from other releasers
            delete this;
        }
    }
};

// Pattern 3: One-time initialisation
class LazyInit {
    std::atomic<void*> ptr{nullptr};
    std::mutex mtx;
public:
    void* get() {
        void* p = ptr.load(std::memory_order_acquire);
        if (p == nullptr) {
            std::lock_guard lock(mtx);
            p = ptr.load(std::memory_order_relaxed);
            if (p == nullptr) {
                p = create();
                ptr.store(p, std::memory_order_release);
            }
        }
        return p;
    }
};
```

### 6. Rust atomics

```rust
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::Arc;

// Simple counter
let counter = Arc::new(AtomicUsize::new(0));

// Increment
counter.fetch_add(1, Ordering::Relaxed);

// Read
let val = counter.load(Ordering::Relaxed);

// Publish/subscribe pattern
static READY: AtomicBool = AtomicBool::new(false);

// Publisher thread
unsafe { DATA = 42; }  // Write data
READY.store(true, Ordering::Release);  // Signal

// Subscriber thread
while !READY.load(Ordering::Acquire) {}
let d = unsafe { DATA };  // Safe: guaranteed to see publisher's write
```

### 7. Fences

Fences provide ordering without an atomic operation on a specific variable:

```cpp
// C++ fence — equivalent to a global memory barrier
std::atomic_thread_fence(std::memory_order_acquire);  // Acquire fence
std::atomic_thread_fence(std::memory_order_release);  // Release fence

// Typical use: multiple atomic writes then one fence
relaxed_atomic_a.store(1, std::memory_order_relaxed);
relaxed_atomic_b.store(2, std::memory_order_relaxed);
std::atomic_thread_fence(std::memory_order_release);  // barrier for all above
sentinel.store(true, std::memory_order_relaxed);
```

### 8. Common mistakes

| Mistake | Fix |
|---------|-----|
| Using Relaxed for publish/subscribe | Use Release on store, Acquire on load |
| Using SeqCst everywhere | Profile first; use weakest correct ordering |
| Forgetting that non-atomic loads are not atomic | All shared mutable data needs atomic or mutex |
| Using `volatile` for thread safety in C++ | `volatile` is not a memory ordering tool; use `atomic` |
| Assuming sequential consistency without SeqCst | Each platform has different default consistency |

For memory ordering rules and happens-before reference, see [references/cpp-memory-ordering.md](references/cpp-memory-ordering.md).

## Related skills

- Use `skills/runtimes/sanitizers` — TSan detects data races involving non-atomic accesses
- Use `skills/rust/rust-sanitizers-miri` for detecting Rust memory ordering violations with Miri
- Use `skills/low-level-programming/assembly-x86` to understand generated fence instructions
- Use `skills/debuggers/gdb` for debugging concurrent programs with thread inspection

© mohitmishra786 · MIT · mohitmishra786/low-level-dev-skills

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой