gpt4 book ai didi

go - 为什么这些 goroutines 的 WaitGroups 不能正常工作?

转载 作者:IT王子 更新时间:2023-10-29 02:25:47 26 4
gpt4 key购买 nike

此代码用于我的编程语言类(class)的一个相当简单的演示。我正在尝试展示 Go 允许的一些不同技术,例如接口(interface)和并发性,但我似乎无法让 WaitGroups 正常工作,所以它最终让我陷入僵局。我最大的问题是:如何让 WaitGroups 正确同步并且在 goroutines 停止时不会死锁系统?我很可能遗漏了一些明显的东西。

package main

import (
"bufio"
"fmt"
"os"
"sync"
)


func Reader(wg *sync.WaitGroup, message chan string, done chan bool){
defer wg.Done()
reader := bufio.NewReader(os.Stdin)
for {

msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
<-done
return
} else {
message <- msg
}

}

}

func main() {
message := make(chan string)
done := make(chan bool)
wg := &sync.WaitGroup{}


wg.Add(1)
go Reader(wg, message, done)


wg.Add(1)
go func(){
defer wg.Done()
for {
select {
case <-done:
return
case msg := <-message:
fmt.Println("main: "+msg)
}
}

}()

wg.Wait()
close(message)
close(done)


}

最佳答案

您在 main 中的 break 语句会中断 select,而不是 for 循环。使用返回或 label相反:

go func() {
defer wg.Done()
for {
select {
case <-done:
return // don't break here without label
case msg := <-message:
fmt.Println("main: " + msg)
}
}
}()

此外,这两个函数都尝试从 done 接收。读者应该关闭 channel 而不是发出完成信号:

func Reader(wg *sync.WaitGroup, message chan string, done chan bool) {
defer wg.Done()
defer close(done) // close channel to signal completion

reader := bufio.NewReader(os.Stdin)
for {
msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
return
} else {
message <- msg
}
}
}

不要关闭主 channel 。发送方应始终关闭 channel 。

完成所有操作后,您应该认识到该消息和完成是多余的。整个程序可以简化为:

package main

import (
"bufio"
"fmt"
"os"
)

func Reader(message chan string) {
defer close(message)

reader := bufio.NewReader(os.Stdin)
for {
msg, _ := reader.ReadString('\n')
if msg == "exit\n" {
return
} else {
message <- msg
}
}
}

func main() {
message := make(chan string)
go Reader(message)

for msg := range message {
fmt.Println("main: " + msg)
}
}

关于go - 为什么这些 goroutines 的 WaitGroups 不能正常工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49789550/

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