在Kubernetes Go repo on Github.com内,
HighWaterMark数据结构的无锁实现。此代码依赖于原子操作来实现没有数据争用的线程安全代码。
// HighWaterMark is a thread-safe object for tracking the maximum value seen
// for some quantity.
type HighWaterMark int64
// Update returns true if and only if 'current' is the highest value ever seen.
func (hwm *HighWaterMark) Update(current int64) bool {
for {
old := atomic.LoadInt64((*int64)(hwm))
if current <= old {
return false
}
if atomic.CompareAndSwapInt64((*int64)(hwm), old, current) {
return true
}
}
}
此代码依赖于标准库中的atomic.LoadInt64
和atomic.CompareAndSwapInt64
函数来实现数据竞争免费代码......我相信它确实存在,但我相信存在竞争条件的另一个问题。
如果两个竞争线程(goroutines
)正在执行此类代码,则存在边缘情况,其中在第一个线程中发生atomic.LoadInt64
之后,第二个线程可能已换出更高的值。但是在第一个线程认为后,current
int64实际上大于old
int64,就会发生交换。然后,由于观察到陈旧的old
值,此交换将有效地降低存储值。
答案 0 :(得分:1)
如果另一个线程进入中间,则CompareAndSwap将失败并且循环将重新开始。
将CompareAndSwap视为
if actual == expected {
actual = newval
}
但原子地完成
所以这段代码说:
old = hwm // but done in a thread safe atomic read way
if old < current {
set hwm to current if hwm == old // atomically compare and then set value
}
当CAS(CompareAndSwap)失败时,它返回false,导致循环重新开始,直到:
a)&#34;当前&#34;不大于hwm
或
b)它成功执行Load,然后是CompareAndSwap而中间没有另一个线程