gpt4 book ai didi

go - 所有的 goroutines 都睡着了——僵局!与 WaitGroup

转载 作者:IT王子 更新时间:2023-10-29 01:11:57 27 4
gpt4 key购买 nike

这是我的代码,我哪里出错了?

func main() {
intChan := make(chan int)
wg := sync.WaitGroup{}

for i := 0;i<5;i++{
wg.Add(1)
go send(intChan,i,&wg)
}

wg.Add(1)
go get(intChan,&wg)
wg.Wait()
time.Sleep(5*time.Second)
close(intChan)
}

func send(c chan int,index int,wg *sync.WaitGroup){
defer func() {
wg.Done()
}()

c <- index
}

func get(c chan int,wg *sync.WaitGroup){
defer func() {
wg.Done()
}()

for i := range c{
fmt.Printf("%d\n",i)
}
}

当我运行它时,我收到错误 fatal error: all goroutines are asleep - deadlock!

这里是错误信息:

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc0000120d8)
C:/Go/src/runtime/sema.go:56 +0x40
sync.(*WaitGroup).Wait(0xc0000120d0)
C:/Go/src/sync/waitgroup.go:130 +0x6b
main.main()
F:/go/src/demo/channel.go:94 +0xf9

goroutine 10 [chan receive]:
main.get(0xc00001c120, 0xc0000120d0)
F:/go/src/demo/channel.go:112 +0xe0
created by main.main
F:/go/src/demo/channel.go:92 +0xeb

谢谢大家,这是我的第一个问题。

最佳答案

正如 Andy 在评论中所说,您只会在收到所有输入并关闭 channel 后退出 get 函数。如您所知,要接收五件东西,​​您可以在发送中使用类似的 for 循环:

func main() {
intChan := make(chan int)
wg := sync.WaitGroup{}

for i := 0; i < 5; i++ {
wg.Add(1)
go send(intChan, i, &wg)
}

wg.Add(1)
go get(intChan, &wg)
wg.Wait()
close(intChan)
}

func send(c chan int, index int, wg *sync.WaitGroup) {
defer func() {
wg.Done()
}()

c <- index
}

func get(c chan int, wg *sync.WaitGroup) {
defer func() {
wg.Done()
}()

for i := 0; i < 5; i++ {
input := <- c
fmt.Printf("%d\n", input)
}
}

https://play.golang.org/p/CB8HUKPBu2I

如果你想坚持在 channel 上进行范围调整,那么你必须在所有消息发送完毕后关闭它,我会通过添加第二个 WaitGroup 来完成:

func main() {
intChan := make(chan int)
allSent := sync.WaitGroup{}

for i := 0; i < 5; i++ {
allSent.Add(1)
go send(intChan, i, &allSent)
}

allReceived := sync.WaitGroup{}
allReceived.Add(1)
go get(intChan, &allReceived)

allSent.Wait()
close(intChan)
allReceived.Wait()
}

func send(c chan int, index int, wg *sync.WaitGroup) {
defer func() {
wg.Done()
}()

c <- index
}

func get(c chan int, wg *sync.WaitGroup) {
defer func() {
wg.Done()
}()

for i := range c {
fmt.Printf("%d\n", i)
}
}

https://play.golang.org/p/svFVrBdwmAc

关于go - 所有的 goroutines 都睡着了——僵局!与 WaitGroup ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54339304/

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