如何在golang中使用atomic的Load和Store
How to use Load and Store of atomic in golang
下面是使用atomic.Value测试结构B的读写互访的一段代码,但我遇到了一些错误,指示无效指针访问。所以我该怎么做?这样做的惯用语是什么?
type A struct {
numMap map[string]int
}
type B struct {
numMap map[string]*A
}
var store atomic.Value
var chanA chan bool = make(chan bool, 100)
var chanB chan bool = make(chan bool, 100)
var b *B = &B{}
func fetchB() {
for i := 0; i < 10000; i++ {
c := store.Load().(B)
for k, v := range c.numMap {
fmt.Println(k, v)
for k2, v2 := range v.numMap {
fmt.Println(k2, v2)
}
}
}
chanA <- true
}
func writeB() {
for i := 0; i < 10000; i++ {
//b := store.Load().(B)
a := new(A)
a.numMap = make(map[string]int)
a.numMap["AMap"] = i
b.numMap = make(map[string]*A)
b.numMap["str"] = a
b.numMap["strA"] = a
delete(b.numMap, "str")
delete(b.numMap["strA"].numMap, "AMap")
store.Store(b)
}
chanB <- true
}
func main() {
store.Store(*b)
for i := 0; i < 100; i++ {
go writeB()
go fetchB()
}
for i := 0; i < 100; i++ {
<-chanA
<-chanB
}
}
很抱歉,我在问题的第一个 post 中遗漏了一些内容。如果我评论 b := store.Load().(B) 错误会出现,如果我让它可见,它就会消失。那为什么会这样呢?
我得到的错误是这样的:
panic: sync/atomic: store of inconsistently typed value into Value
goroutine 5 [running]: sync/atomic.(*Value).Store(0x597310, 0x4b7f40, 0x597198)
/usr/local/go/src/sync/atomic/value.go:76 +0x1e9 main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:47 +0x2cc created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x71
goroutine 1 [chan receive]: main.main()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:59 +0xf3
goroutine 6 [runnable]: main.fetchB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:23 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:55 +0x89
goroutine 7 [runnable]: main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:36 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x71
goroutine 8 [runnable]: main.fetchB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:23 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:55 +0x89
goroutine 9 [runnable]: main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:36 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x7
当您注释掉 b := store.Load().(B)
时,函数中使用的变量 b
是 *B
类型的全局 b
并且当您执行 store.Store(b)
你得到错误是因为你试图在存储中存储 *B
类型的值,该值的类型为 B
。这就是错误谈论不一致类型的原因。您可以将 store.Store(b)
更改为 store.Store(*b)
,代码将正常运行。
下面是使用atomic.Value测试结构B的读写互访的一段代码,但我遇到了一些错误,指示无效指针访问。所以我该怎么做?这样做的惯用语是什么?
type A struct {
numMap map[string]int
}
type B struct {
numMap map[string]*A
}
var store atomic.Value
var chanA chan bool = make(chan bool, 100)
var chanB chan bool = make(chan bool, 100)
var b *B = &B{}
func fetchB() {
for i := 0; i < 10000; i++ {
c := store.Load().(B)
for k, v := range c.numMap {
fmt.Println(k, v)
for k2, v2 := range v.numMap {
fmt.Println(k2, v2)
}
}
}
chanA <- true
}
func writeB() {
for i := 0; i < 10000; i++ {
//b := store.Load().(B)
a := new(A)
a.numMap = make(map[string]int)
a.numMap["AMap"] = i
b.numMap = make(map[string]*A)
b.numMap["str"] = a
b.numMap["strA"] = a
delete(b.numMap, "str")
delete(b.numMap["strA"].numMap, "AMap")
store.Store(b)
}
chanB <- true
}
func main() {
store.Store(*b)
for i := 0; i < 100; i++ {
go writeB()
go fetchB()
}
for i := 0; i < 100; i++ {
<-chanA
<-chanB
}
}
很抱歉,我在问题的第一个 post 中遗漏了一些内容。如果我评论 b := store.Load().(B) 错误会出现,如果我让它可见,它就会消失。那为什么会这样呢?
我得到的错误是这样的:
panic: sync/atomic: store of inconsistently typed value into Value
goroutine 5 [running]: sync/atomic.(*Value).Store(0x597310, 0x4b7f40, 0x597198)
/usr/local/go/src/sync/atomic/value.go:76 +0x1e9 main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:47 +0x2cc created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x71
goroutine 1 [chan receive]: main.main()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:59 +0xf3
goroutine 6 [runnable]: main.fetchB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:23 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:55 +0x89
goroutine 7 [runnable]: main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:36 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x71
goroutine 8 [runnable]: main.fetchB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:23 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:55 +0x89
goroutine 9 [runnable]: main.writeB()
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:36 created by main.main
/home/bzhang/devCode/common/src/go/src/audience_service/test.go:54 +0x7
当您注释掉 b := store.Load().(B)
时,函数中使用的变量 b
是 *B
类型的全局 b
并且当您执行 store.Store(b)
你得到错误是因为你试图在存储中存储 *B
类型的值,该值的类型为 B
。这就是错误谈论不一致类型的原因。您可以将 store.Store(b)
更改为 store.Store(*b)
,代码将正常运行。