以下无锁代码是否表现出竞争条件?
Does the following lock-free code exhibit a race-condition?
在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
值,此交换将有效地降低存储值。
如果中间有另一个线程,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) 失败时,它 returns 为假,导致循环重新开始,直到:
a) "current" 不大于 hwm
或
b) 它成功地执行了 Load,然后是 CompareAndSwap,中间没有另一个线程
在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
值,此交换将有效地降低存储值。
如果中间有另一个线程,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) 失败时,它 returns 为假,导致循环重新开始,直到:
a) "current" 不大于 hwm
或
b) 它成功地执行了 Load,然后是 CompareAndSwap,中间没有另一个线程