Go 定义类型上的原子操作
如果我定义一种新类型的“状态”,如下所示:Go 定义类型上的原子操作,go,Go,如果我定义一种新类型的“状态”,如下所示: type State int32 类型“State”的值是否可以应用于原子操作,如“atomic.StoreInt32()” 若否,原因为何 如果可以,是否可以按以下方式应用 func SetAndGet(s State, n State) State { si := int32(s) ni := int32(n) return State(atomic.SwapInt32(&si, ni)) } 更新: 根据@i
type State int32
类型“State”的值是否可以应用于原子操作,如“atomic.StoreInt32()”
若否,原因为何
如果可以,是否可以按以下方式应用
func SetAndGet(s State, n State) State {
si := int32(s)
ni := int32(n)
return State(atomic.SwapInt32(&si, ni))
}
更新: 根据@icza的回答,代码修改如下
func SetAndGetState(s *State, n State) State {
return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
func SetAndGetInt(s *int32, n int32) State {
return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
var s1 State = 1
var i1 int32 = 1
SetAndGetState(&s1, 2)
SetAndGetInt(&i1, 2)
我试过我和@icza的密码。他们都成功了。“State”的结果似乎与int32相同。我想知道的是:
在高并发情况下,原子操作对定义类型“State”的并发效果是否与对“int32”的并发效果相同 原子操作通常在变量上执行 调用函数时,将复制传递的值。没有理由对仅由函数使用的局部变量(函数参数)执行原子操作 您可能希望执行原子操作,例如对全局变量执行原子操作。要想做到这一点,您必须传递它的地址(传递它的值只是复制它) 而且,您不能创建所传递指针的本地副本(也不能创建指向的值),必须将获得的地址直接传递到
atomic.SwapInt32()
。要做到这一点,只需将*State
指针转换为*int32
。这是可能的,因为State
将int32
作为其基础类型:
func SetAndGet(s *State, n State) State {
return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
测试它:
var s State
func main() {
fmt.Println(SetAndGet(&s, 1))
fmt.Println(SetAndGet(&s, 2))
fmt.Println(SetAndGet(&s, 3))
}
输出(在上尝试):
使用上述解决方案,您可以获得与使用
int32
而不是State
时相同的并发保证,原子操作通常对变量执行
调用函数时,将复制传递的值。没有理由对仅由函数使用的局部变量(函数参数)执行原子操作
您可能希望执行原子操作,例如对全局变量执行原子操作。要想做到这一点,您必须传递它的地址(传递它的值只是复制它)
而且,您不能创建所传递指针的本地副本(也不能创建指向的值),必须将获得的地址直接传递到atomic.SwapInt32()
。要做到这一点,只需将*State
指针转换为*int32
。这是可能的,因为State
将int32
作为其基础类型:
func SetAndGet(s *State, n State) State {
return State(atomic.SwapInt32((*int32)(s), int32(n)))
}
测试它:
var s State
func main() {
fmt.Println(SetAndGet(&s, 1))
fmt.Println(SetAndGet(&s, 2))
fmt.Println(SetAndGet(&s, 3))
}
输出(在上尝试):
使用上述解决方案,您可以获得与使用
int32
而不是State
相同的并发性保证。尝试时会发生什么?只需实现这三行代码并测试它们,然后继续问,可能会快得多?“是”是答案的缩写。对不起。我已经添加了更多我想知道的细节。我测试的结果似乎是正确的。但我想知道,在高并发情况下,当遇到原子操作时,是否可以使用定义的类型“State”而不是“int32”。如果您尝试,会发生什么?只实现这三行代码并测试它们可能会快得多,然后继续问?“是”是答案的缩写。对不起。我已经添加了更多我想知道的细节。我测试的结果似乎是正确的。但我想知道,在高并发情况下,当遇到原子操作时,是否可以使用定义的类型“State”来代替“int32”。这是否意味着在高并发情况下,原子操作对定义的类型“State”的并发效果与对“int32”的并发效果相同?@JunfeiHu是的,您将获得与使用int32
相同的并发保证。这是否意味着,在高并发情况下,原子操作对定义类型“State”的并发效果与对“int32”的并发效果相同?@JunfeiHu是的,您将获得与使用int32
相同的并发保证。