重点是进展,不是没有lock字样
传统临界区若由一个暂停的执行者持锁,其他需要同一锁的执行者可能一起无法前进。无锁设计要避免把整个并发对象的进展绑在这一持有者身上;用自旋反复等待锁位,并不会因此变成无锁算法。
整体进展与个体完成不同。无锁性质允许某个操作持续输掉竞争,而其他操作不断成功;Herlihy提出的无等待条件更强,要求每个参与执行的进程都能在有限自身步骤内完成操作,不受其他进程速度支配。
比较交换怎样支持重试
一种常见方法是先读取状态,算出候选新状态,再用比较交换确认原值仍符合预期,成功才提交。若竞争改变了原值,调用者重新读取或利用失败返回的当前值,再计算候选结果;它不是无条件覆盖别人的更新。
C++比较交换失败时会更新expected,弱形式还允许虚假失败,因此重试规则必须与接口吻合。比较交换只是构造并发算法的原语,不能只看到循环里用了它,就推断整个数据结构已经正确或满足无锁进展。
原子性、无锁性与实际成本分开
原子操作不一定由无锁机制实现。C++提供is_lock_free等查询,并明确非无锁原子操作可能阻塞;算法依赖的类型、平台和操作范围,都要与声称的进展保证一致。
即使核心更新满足无锁性质,外围内存分配、资源回收或其他调用仍可能改变整个接口的进展边界。无锁也不自动限制重试次数或保证低延迟;竞争和缓存通信可产生额外成本,正确性、进展与性能应分别验证。