plugins/languages/cpp/skills/concurrency/SKILL.md
C++ concurrency with C++20/23/26 primitives: std::jthread, stop_token, scoped_lock, latch / barrier, atomics with memory ordering, coroutines (task / generator), parallel algorithms, std::execution senders/receivers, lock-free patterns, TSan. Use when writing multithreaded, async, or thread-safe code, or diagnosing data races. Also triggers on "多线程", "并发", "jthread", "stop_token", "协程", "coroutine", "atomic", "memory_order", "data race", "TSan", "ThreadSanitizer", "lock-free", "std::execution", "senders receivers".
npx skillsauth add lazygophers/ccplugin cpp-concurrencyInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
线程模型必须以现代 C++ 同步原语 + RAII 锁 + 工具诊断为基线。所有共享可变状态必须经 TSan 验证。
#include <thread>
#include <stop_token>
// 自动 join + 协作式取消
std::jthread worker([](std::stop_token st) {
while (!st.stop_requested()) {
if (!process_one()) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
}
});
// 析构时自动 request_stop() + join()
禁用裸 std::thread 除非确需脱钩生命期。
std::mutex a_mtx, b_mtx;
void transfer(Account& a, Account& b, int amount) {
std::scoped_lock lock(a_mtx, b_mtx); // 死锁规避算法
a.balance -= amount;
b.balance += amount;
}
禁用 std::lock_guard 多锁场景。
// latch:一次性倒计时
std::latch ready(worker_count);
for (size_t i = 0; i < worker_count; ++i) {
pool.submit([&, i] { warmup(i); ready.count_down(); });
}
ready.wait();
// barrier:可复用同步点 + 阶段完成回调
std::barrier sync(worker_count, [] noexcept { swap_buffers(); });
for (auto& w : workers) {
w = std::jthread([&](std::stop_token st) {
while (!st.stop_requested()) {
compute_phase();
sync.arrive_and_wait();
}
});
}
std::mutex mtx;
std::condition_variable_any cv;
std::queue<Job> q;
void consumer(std::stop_token st) {
std::unique_lock lk(mtx);
while (cv.wait(lk, st, [&] { return !q.empty(); })) {
auto job = std::move(q.front()); q.pop();
lk.unlock();
run(job);
lk.lock();
}
}
std::atomic<int> counter{0};
// 默认 seq_cst:最严格,性能最差
counter.fetch_add(1);
// relaxed:仅原子性,无序保证(计数器、统计)
counter.fetch_add(1, std::memory_order_relaxed);
// release/acquire:生产消费同步
std::atomic<bool> ready{false};
int data = 0;
// Producer
data = 42;
ready.store(true, std::memory_order_release);
// Consumer
while (!ready.load(std::memory_order_acquire)) {}
assert(data == 42); // happens-before 保证
// std::atomic_ref(C++20):作用于非原子变量
int value = 0;
std::atomic_ref<int> ref(value);
ref.fetch_add(1);
memory_order 选择决策必须在代码注释中说明 why。
#include <generator>
std::generator<int> fibonacci() {
int a = 0, b = 1;
while (true) {
co_yield a;
auto next = a + b;
a = b; b = next;
}
}
for (int x : fibonacci() | std::views::take(10)) std::println("{}", x);
template<typename T>
struct Task {
struct promise_type {
T value_{};
Task get_return_object() {
return Task{std::coroutine_handle<promise_type>::from_promise(*this)};
}
std::suspend_never initial_suspend() noexcept { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void return_value(T v) { value_ = std::move(v); }
void unhandled_exception() { std::terminate(); }
};
std::coroutine_handle<promise_type> handle;
~Task() { if (handle) handle.destroy(); }
T result() { return std::move(handle.promise().value_); }
};
生产代码优先选择成熟库(cppcoro, folly::coro, unifex, stdexec)。
P2300 senders/receivers 是 C++26 的结构化并发框架。当前可用 stdexec 库(NVIDIA)。
#include <stdexec/execution.hpp>
#include <exec/static_thread_pool.hpp>
namespace ex = stdexec;
exec::static_thread_pool pool(4);
auto sched = pool.get_scheduler();
auto work = ex::schedule(sched)
| ex::then([] { return load_data(); })
| ex::then([](auto data) { return process(data); })
| ex::then([](auto result) { return save(result); });
auto [result] = ex::sync_wait(std::move(work)).value();
C++26 标准化时切换到 std::execution。
#include <execution>
#include <algorithm>
// 顺序 / 并行 / 并行+向量化
std::sort(std::execution::par, v.begin(), v.end());
std::transform_reduce(std::execution::par_unseq,
v.begin(), v.end(), 0L, std::plus{}, [](int x) { return x*x; });
// C++26(提案):ranges 版并行
// std::ranges::sort(std::execution::par_unseq, v);
注意:par_unseq 函数体禁止任何同步原语。
// 不同线程更新各自字段时,按缓存行隔离
struct alignas(std::hardware_destructive_interference_size) PaddedCounter {
std::atomic<int64_t> value{0};
};
std::array<PaddedCounter, max_threads> counters;
template<typename T>
class LockFreeStack {
struct Node { T data; Node* next; };
std::atomic<Node*> head_{nullptr};
public:
void push(T value) {
auto* node = new Node{std::move(value), head_.load(std::memory_order_relaxed)};
while (!head_.compare_exchange_weak(
node->next, node,
std::memory_order_release,
std::memory_order_relaxed)) {}
}
// pop 涉及 ABA 问题,生产实现需 hazard pointer / RCU
};
未掌握 ABA / hazard pointer / 内存回收前不要写自定义 lock-free。
# ThreadSanitizer:data race / lock-order inversion
g++ -fsanitize=thread -fno-omit-frame-pointer -g -O1 src/*.cpp
# Helgrind(Valgrind)
valgrind --tool=helgrind ./app
TSan 与 ASan 互斥;CI 跑两条管道。
| 借口 | 检查项 |
|------|--------|
| "std::thread 简单" | 是否换 std::jthread(自动 join + stop_token)? |
| "lock_guard 足够" | 多锁场景是否换 std::scoped_lock? |
| "睡一下就同步" | 是否使用 latch/barrier/condition_variable? |
| "全 seq_cst" | relaxed / acquire-release 是否够?是否注释 why? |
| "不跑 TSan" | 并发代码 CI 是否过 TSan? |
| "自己写 lock-free 更快" | 是否处理 ABA、hazard pointer、内存序? |
std::jthread + stop_tokenstd::scoped_lockstd::executiontools
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。