golang Map 并发安全的几个点 发表于 2018-01-30 | 分类于 Golang 有几个坑,需要注意一下 实现112345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970//// map_safe.go// Copyright (C) 2018 chentao <chentao@chentaos-MacBook-Pro.local>//// Distributed under terms of the MIT license.//package mainimport ( "fmt" "sync" "time")type ctr struct { sync.RWMutex m map[string]int}func main() { counter := &ctr{m: make(map[string]int)} for i := 0; i < 10; i++ { go bc(counter) } //for i := 0; i < 10; i++ { // go set(counter, i*10) //} //for i := 0; i < 10; i++ { // go get(counter) //} time.Sleep(time.Second * 2)}func bc(counter *ctr) { for i := 0; i < 10; i++ { go set(counter, i) } for i := 0; i < 10; i++ { go get(counter) }}// counter 这里必须是引用func set(counter *ctr, v int) { counter.Lock() defer func() { counter.Unlock() fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex) fmt.Printf("set unlock count addr %p \n", &counter.m) fmt.Printf("set unlock all addr %p \n", &counter) }() //counter.m["some_key"] = v counter.m["some_key"] = counter.m["some_key"] + v //time.Sleep(time.Millisecond * 10) fmt.Println("some_key set:", counter.m["some_key"])}func get(counter *ctr) { counter.RLock() defer func() { counter.RUnlock() fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex) fmt.Printf("get unlock count addr %p \n", &counter.m) fmt.Printf("get unlock all addr %p \n", &counter) }() n := counter.m["some_key"] fmt.Println("some_key get:", n)} 实现2123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475//// map_safe.go// Copyright (C) 2018 chentao <chentao@chentaos-MacBook-Pro.local>//// Distributed under terms of the MIT license.//package mainimport ( "fmt" "sync" "time" "unsafe")type ctr2 struct { sync.RWMutex m map[string]int}func main() { counter := ctr2{m: make(map[string]int)} for i := 0; i < 10; i++ { go counter.bc() } //for i := 0; i < 10; i++ { // go set(counter, i*10) //} //for i := 0; i < 10; i++ { // go get(counter) //} time.Sleep(time.Second * 2)}// counter这里都OKfunc (counter *ctr2) bc() { for i := 0; i < 10; i++ { go counter.set(i) } for i := 0; i < 10; i++ { go counter.get() }}func (counter *ctr2) set(v int) { counter.Lock() defer func() { counter.Unlock() fmt.Printf("set unlock mutex addr %p \n", &counter.RWMutex) fmt.Printf("set unlock count addr %p \n", &counter.m) fmt.Printf("set unlock all addr %p \n", &(*counter)) fmt.Printf("set unlock all addr %p \n", unsafe.Pointer(counter)) fmt.Printf("set unlock all addr %p \n", counter) }() // 注意这几个对象引用和地址的区分 //counter.m["some_key"] = v counter.m["some_key"] = counter.m["some_key"] + v //time.Sleep(time.Millisecond * 10) fmt.Println("some_key set:", counter.m["some_key"])}func (counter *ctr2) get() { counter.RLock() defer func() { counter.RUnlock() fmt.Printf("get unlock mutex addr %p \n", &counter.RWMutex) fmt.Printf("get unlock count addr %p \n", &counter.m) fmt.Printf("get unlock all addr %p \n", &(*counter)) fmt.Printf("get unlock all addr %p \n", unsafe.Pointer(counter)) fmt.Printf("get unlock all addr %p \n", counter) }() n := counter.m["some_key"] fmt.Println("some_key get:", n)}