gpt4 book ai didi

go - 使用 goroutine 和闭包从并发函数读取并发错误

转载 作者:IT王子 更新时间:2023-10-29 01:51:05 24 4
gpt4 key购买 nike

我有一个正在写入 channel 的函数(不是闭包)。我正在从 goroutine 中调用该函数作为

var wg sync.WaitGroup
wg.Add(1)
go DoStuff(somechan, &wg)

在 DoStuff 中,我有类似的东西

for ; ; {

if err == io.EOF {
fmt.Println(err)
close(somechan)
fmt.Println("Closed channel")
break
} else if err != nil {
panic(err)
}
somechan <- Somefunc()
}

现在我正在尝试使用另一个 goroutine 从该 channel 读取数据。

wgread.Add(1)
go func() {
for ; ; {
select {
case chanoutput, ok := <-somechan:
if ok == true {
fmt.Println(string(*chanoutput))
} else {
fmt.Println("DONE")
fmt.Println(ok)
wgread.Done()
break
}
}

}
}()
wgread.Wait()

但是,在运行时,我得到了

panic: sync: negative WaitGroup counter

打印后

DONE
false
DONE
false

如果我给 wgread.Add(2),它会打印上面的 DONE 和 false 3 次。

虽然我将 WaitGroup 增量递增 1,但为什么给出负 WaitGroup 计数器错误?使用另一个并发函数或闭包从 goroutine 读取数据的最佳方式是什么?

最佳答案

break 语句跳出最内层的 case,for 或 switch 语句。在 somechan 上接收的函数在一个循环中旋转,当 channel 关闭时递减 WaitGroup 。编写代码如下:

wgread.Add(1)
go func() {
defer wgread.Done()
for chanoutput := range somechan {
fmt.Println(string(*chanoutput))
}
fmt.Println("DONE")
}()
wgread.Wait()

如果接收代码如题中所写,则接收goroutine可以消除。将 wgread.Add(1) 中的代码替换为 wgread.Wait()

for chanoutput := range somechan {
fmt.Println(string(*chanoutput))
}

关于go - 使用 goroutine 和闭包从并发函数读取并发错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38976377/

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