gpt4 book ai didi

go - 具有 WaitGroup 和无缓冲 channel 的竞争条件

转载 作者:IT王子 更新时间:2023-10-29 01:53:46 25 4
gpt4 key购买 nike

在这篇文章中得到我最初问题的(正确)解决方案后 Understanding golang channels: deadlock ,我想出了一个稍微不同的解决方案(在我看来读起来更好:

// 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()

你能帮我了解竞争条件在哪里吗?

最佳答案

您正在尝试从 fmt.Println(histogram) 中的 histogram 中读取,它与 goroutine 的写入不同步 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

您可以做的另一件事是等待 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)

或者干脆使用 channel 等待。

done := make(chan bool)
go func() {
for w := range words {
histogram[w]++
}
done <- true
}()

wg.Wait()
close(words)
<-done

fmt.Println(histogram)

关于go - 具有 WaitGroup 和无缓冲 channel 的竞争条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53693110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com