在本文中了解了我最初的问题的(正确)解决方案之后,了解了golang频道:死锁,我想出了一个略有不同的解决方案(在我看来,这更好看:
// Binary histogram counts the occurences of each word. package main import ( "fmt" "strings" "sync" ) var data = []string{ "The yellow fish swims slowly in the water", "The brown dog barks loudly after a drink ...", "The dark bird bird of prey lands on a small ...", } func main() { histogram := make(map[string]int) words := make(chan string) var wg sync.WaitGroup for _, line := range data { wg.Add(1) go func(l string) { for _, w := range strings.Split(l, " ") { words <- w } wg.Done() }(line) } go func() { for w := range words { histogram[w]++ } }() wg.Wait() close(words) fmt.Println(histogram) }
它确实可以工作,但是不幸的是,它在比赛中运行,它显示了2个比赛条件:
================== WARNING: DATA RACE Read at 0x00c420082180 by main goroutine: ... Previous write at 0x00c420082180 by goroutine 9: ... Goroutine 9 (running) created at: main.main()
您能帮我了解比赛情况吗?
您正在试图从读histogram中fmt.Println(histogram)未同步到够程变异它的写入histogram[w]++。您可以添加锁以同步写入和读取。
histogram
fmt.Println(histogram)
histogram[w]++
例如
var lock sync.Mutex go func() { lock.Lock() defer lock.Unlock() for w := range words { histogram[w]++ } }() //... lock.Lock() fmt.Println(histogram)
请注意,您也可以使用sync.RWMutex。
sync.RWMutex
您可以做的另一件事是等待goroutine变异histogram完成。
var histWG sync.WaitGroup histWG.Add(1) go func() { for w := range words { histogram[w]++ } histWG.Done() }() wg.Wait() close(words) histWG.Wait() fmt.Println(histogram)
或者只是使用频道来等待。
done := make(chan bool) go func() { for w := range words { histogram[w]++ } done <- true }() wg.Wait() close(words) <-done fmt.Println(histogram)