go-map的并发问题
2017-05-08 22:00
387 查看
go 语言的map是引用传递的、如果多个goroutine同时读写,必然导致冲突,所以一般我们在并发操作map的时候,一定要加锁,但是如果map里的value是还是map,那么并发操作这个value- map是不是也一样回引起冲突呢?答案是:是的,go里所有map的并发操作都需要加锁,这样才不会引起冲突,见如下代码。我对map td操作加了锁,对得到的value-map进行了写操作,没有加锁,通过go run -race aa.go 依然可以检测到冲突,所以结论就是:并发读写操作go语言的任何一个map都需要加锁,这样才能防止冲突。
go 自带竞争检测机制调用如下命令
结果如下:
// filename: aa.go import ( "fmt" "sync" "time" ) func main() { td := map[string]map[string]int{"info": {"age": 10}} var Lock sync.Mutex for i := 0; i < 2; i++ { go func(md map[string]map[string]int) { Lock.Lock() info := td["info"] Lock.Unlock() info["age"] = 100 fmt.Println("info:", info["age"]) }(td) } time.Sleep(1 * time.Second) }
go 自带竞争检测机制调用如下命令
go run -race aa.go
结果如下:
info: 100 ================== WARNING: DATA RACE Write at 0x00c4200162a0 by goroutine 6: runtime.mapassign() /home/liuguirong/golang/go/src/runtime/hashmap.go:485 +0x0 main.main.func1() /home/liuguirong/lgr/getiplib/src/aa.go:17 +0xef Previous write at 0x00c4200162a0 by goroutine 7: runtime.mapassign() /home/liuguirong/golang/go/src/runtime/hashmap.go:485 +0x0 main.main.func1() /home/liuguirong/lgr/getiplib/src/aa.go:17 +0xef Goroutine 6 (running) created at: main.main() /home/liuguirong/lgr/getiplib/src/aa.go:19 +0x1eb Goroutine 7 (finished) created at: main.main() /home/liuguirong/lgr/getiplib/src/aa.go:19 +0x1eb ================== ================== WARNING: DATA RACE Write at 0x00c42005c3c8 by goroutine 6: main.main.func1() /home/liuguirong/lgr/getiplib/src/aa.go:17 +0x105 Previous write at 0x00c42005c3c8 by goroutine 7: main.main.func1() /home/liuguirong/lgr/getiplib/src/aa.go:17 +0x105 Goroutine 6 (running) created at: main.main() /home/liuguirong/lgr/getiplib/src/aa.go:19 +0x1eb Goroutine 7 (finished) created at: main.main() /home/liuguirong/lgr/getiplib/src/aa.go:19 +0x1eb ================== info: 100 Found 2 data race(s) exit status 66
相关文章推荐
- go map并发写错误问题
- Go 1.9 以后 map 并发读写的问题,sync.Map 揭秘
- go中利用hmset替换hset来提高redis的存取效率及并发goroutine可能遇到的问题
- Go之并发处理(售票问题)
- Map并发问题
- go语言映射map的线程协程安全问题
- golang中map并发读写问题及解决方法
- go语言函数传递问题(map、切片、接口、chan)
- Map并发问题
- golang map数据结构不能并发读写问题
- Go 中的 map 并发存取
- go的map中struct赋值问题
- 优化 Go 中的 map 并发存取
- go中利用hmset替换hset来提高redis的存取效率及并发goroutine可能遇到的问题
- 优化 Go 中的 map 并发存取
- 关于golang的并发读写访问map问题
- go语言坑之并发访问map
- 如果静态方法里面没有存取静态字段的话, 就没有并发的线程安全的问题...(这句话对吗?)
- tomcat 并发问题 (terminating thread)
- 多用户并发联接解决了,新的问题多多,郁闷的天气,郁闷的人