Fis*_*ish 3 struct dictionary go concurrenthashmap goroutine
concurrentMap()函数Have WARNING: DATA RACE和致命错误:concurrent map read and map write
concurrentStruct() 有警告:数据竞赛,但运行正常
package main
import (
"sync"
)
func main() {
// concurrentMap()
concurrentStruct()
// concurrentStructWithMuLock()
}
type Metadata struct {
mu sync.RWMutex //
key bool
}
// concurrentStruct ???????
// concurrent read and write the struct
// go run -race main.go ? WARNING: DATA RACE???????
// go run -race main.go It have WARNING: DATA RACE, But running ok
func concurrentStruct() {
m := new(Metadata)
for i := 0; i < 100000; i++ {
go func(metadata *Metadata) {
for {
readValue := metadata.key
if readValue {
metadata.key = false
}
}
}(m)
go func(metadata *Metadata) {
for {
metadata.key = true
}
}(m)
}
select {}
}
// concurrentStructWithMuLock ????(??????)???
// concurrent read and write the struct with RWMutex
// go run -race main.go ?? WARNING: DATA RACE
// go run -race main.go Don't have WARNING: DATA RACE, and running ok
func concurrentStructWithMuLock() {
m := new(Metadata)
go func(metadata *Metadata) {
for {
metadata.mu.Lock()
readValue := metadata.key
if readValue {
metadata.key = false
}
metadata.mu.Unlock()
}
}(m)
go func(metadata *Metadata) {
for {
metadata.mu.Lock()
metadata.key = true
metadata.mu.Unlock()
}
}(m)
select {}
}
// concurrentMap ???? Map
// concurrent read and write the map
// go run -race main.go ? WARNING: DATA RACE??????fatal error: concurrent map read and map write
// go run -race main.go Have WARNING: DATA RACE, And fatal error: concurrent map read and map write
func concurrentMap() {
m := make(map[int]int)
go func() {
for {
_ = m[1]
}
}()
go func() {
for {
m[2] = 2
}
}()
select {}
}
Run Code Online (Sandbox Code Playgroud)
未同步,并发访问多个goroutine中的任何变量(其中至少一个是写操作)是未定义的行为。不要尝试以未定义的行为查找逻辑,只需使用适当的同步即可。未定义意味着它可能会“正确”运行,也可能“不正确”运行(给出错误的结果),或者崩溃或发生其他任何情况。那就是未定义的意思。在此处了解更多信息:在没有锁的情况下同时读取函数指针是否安全?
你concurrentStructWithMuLock()居然没有数据的比赛,因为你使用的是互斥正确同步访问结构。
而concurrentMap()这是另一个问题。Go 1.6向运行时添加了轻量级的并发滥用地图检测功能:
运行时增加了轻巧,尽力而为的检测并发滥用地图的功能。与往常一样,如果一个goroutine正在写入地图,则其他goroutine不应同时读取或写入地图。如果运行时检测到这种情况,它将打印诊断并使程序崩溃。找出更多有关该问题的最佳方法是在“ 种族检测器”下运行该程序,这将更可靠地识别种族并提供更多详细信息。
因此,这是运行时的有意崩溃,因为它检测到对映射的非同步访问。这是Go运行时的“功能”,它会使您的应用程序崩溃,因为您的应用程序中不应保留任何数据竞争(以防止发生未定义的行为)。在此处了解更多信息:如何从并发映射写入中恢复?
| 归档时间: |
|
| 查看次数: |
1056 次 |
| 最近记录: |