Go atomic store 后跟 atomic load 在整个例程中表现不正常
Go atomic store followed by atomic load is behaving erratically across routines
我正在尝试将地图存储为不安全。指针并稍后尝试检索它。下面是代码片段:
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
type MapHolder struct {
ptr unsafe.Pointer
}
func (m MapHolder) Set(myMap map[string]int64) {
atomic.StorePointer(&m.ptr, unsafe.Pointer(&myMap))
fmt.Printf("The pointer value is: %v\n", atomic.LoadPointer(&m.ptr))
}
func (m MapHolder) Get() map[string]int64 {
ptr := atomic.LoadPointer(&m.ptr)
if ptr == nil {
fmt.Printf("Why is this pointer value nil?")
return nil
} else {
return *(*map[string]int64)(ptr)
}
}
func main() {
var m MapHolder
test := make(map[string]int64)
test["hello"] = 1
m.Set(test)
m.Get()
}
当Set()
执行时,它会正确打印m.ptr
的内容。但是,当我们执行 Get()
时,它 returns nil。这看起来完全出乎我的意料。我正在使用 go 1.11.6
以上程序的输出为:
The pointer loaded is: 0x40c130
为什么这个指针值为零?
因为Set
方法有一个值接收者,当方法returns时,接收者值和对值的任何更改都将被丢弃。使用指针接收器解决问题。
func (m *MapHolder) Set(myMap map[string]int64) { ... }
func (m *MapHolder) Get() map[string]int64 { ... }
Get
方法还必须使用指针接收器来防止接收器参数副本上的数据竞争。
Set
方法存储参数 myMap
的地址,而不是 main
中 m
的地址。这可能是问题,也可能不是问题,具体取决于应用程序如何使用 MapHolder
.
我正在尝试将地图存储为不安全。指针并稍后尝试检索它。下面是代码片段:
package main
import (
"fmt"
"sync/atomic"
"unsafe"
)
type MapHolder struct {
ptr unsafe.Pointer
}
func (m MapHolder) Set(myMap map[string]int64) {
atomic.StorePointer(&m.ptr, unsafe.Pointer(&myMap))
fmt.Printf("The pointer value is: %v\n", atomic.LoadPointer(&m.ptr))
}
func (m MapHolder) Get() map[string]int64 {
ptr := atomic.LoadPointer(&m.ptr)
if ptr == nil {
fmt.Printf("Why is this pointer value nil?")
return nil
} else {
return *(*map[string]int64)(ptr)
}
}
func main() {
var m MapHolder
test := make(map[string]int64)
test["hello"] = 1
m.Set(test)
m.Get()
}
当Set()
执行时,它会正确打印m.ptr
的内容。但是,当我们执行 Get()
时,它 returns nil。这看起来完全出乎我的意料。我正在使用 go 1.11.6
以上程序的输出为:
The pointer loaded is: 0x40c130
为什么这个指针值为零?
因为Set
方法有一个值接收者,当方法returns时,接收者值和对值的任何更改都将被丢弃。使用指针接收器解决问题。
func (m *MapHolder) Set(myMap map[string]int64) { ... }
func (m *MapHolder) Get() map[string]int64 { ... }
Get
方法还必须使用指针接收器来防止接收器参数副本上的数据竞争。
Set
方法存储参数 myMap
的地址,而不是 main
中 m
的地址。这可能是问题,也可能不是问题,具体取决于应用程序如何使用 MapHolder
.