wait-free编程¶
- 定义:每线程有限步完成,调度/挂起不影响;强于 lock-free,杜绝饥饿和无界自旋。
- 核心机制:Helping 协作,线程遇到未完成操作时主动帮忙完成,避免重试循环。
- 状态编码:高位放标志位(如 is_zero、helped),一次原子读写携带数据+状态。
- 线性一致性:用逻辑顺序解释交错,当 CAS 失败因他人修改时直接判定顺序并返回,无需自旋。
- 适用:读多写少、对 P99/P999 极敏感或不可阻塞的底层场景(引用计数、低延迟渠道)。
- 取舍:更多原子/状态判断,代码复杂;写密集或对尾延迟不敏感时,lock-free/自旋锁可能更优。
Wait-Free Sticky Counter 示例
#include <atomic>
#include <cstdint>
struct WaitFreeCounter {
static constexpr uint64_t is_zero = 1ull << 63;
static constexpr uint64_t helped = 1ull << 62;
std::atomic<uint64_t> counter{1}; // 低 62 位为计数
uint64_t read() {
uint64_t val = counter.load(std::memory_order_acquire);
if (val == 0 && counter.compare_exchange_strong(
val, is_zero | helped, std::memory_order_acq_rel)) {
return 0; // 帮忙固化零
}
return (val & is_zero) ? 0 : (val & ~(is_zero | helped));
}
bool decrement() {
if (counter.fetch_sub(1, std::memory_order_acq_rel) == 1) {
uint64_t expect = 0;
if (counter.compare_exchange_strong(expect, is_zero,
std::memory_order_acq_rel)) {
return true; // 自己固化零
} else if ((expect & helped) &&
(counter.exchange(is_zero, std::memory_order_acq_rel) &
helped)) {
return true; // 已被协助固化
}
}
return false; // 未归零或逻辑顺序上被加回
}
bool increment_if_not_zero() {
return (counter.fetch_add(1, std::memory_order_acq_rel) & is_zero) == 0;
}
};
提示:用高位偷位携带状态,读操作也参与协助;无循环,自旋抖动被消除。