gpt4 book ai didi

具有 sync.WaitGroup 的 Goroutine 在最后一个 wg.Done() 之前结束

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

我有一个示例代码(您可以在 Go Playground 上找到它):

package main

import (
"fmt"
"sync"
"time"
)

func main() {
messages := make(chan int)
var wg sync.WaitGroup
var result []int

// you can also add these one at
// a time if you need to

wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 1
}()
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 2
}()
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 3
}()
go func() {
for i := range messages {
fmt.Println(i)
result = append(result, i)
}

}()

wg.Wait()
fmt.Println(result)
}

我得到了这个输出:

2
1
[2 1]

我想我知道为什么会这样,但我无法解决它。 WaitGroup 中有 3 个项目,我的意思是三个 goroutine,第 4 个 groutine 使用 channel 中的数据。当最后一个 groutine 说 wg.Done() 程序结束,因为 wg.Wait() 说每个 goroutine 都完成了,最后一个 goroutine 结果第四个 goroutine 不能消费,因为程序结束了。我尝试在第 4 个函数中使用 wg.Add(1) 和 wg.Done() 添加加一,但在这种情况下我遇到了死锁。

最佳答案

关闭 channel 是一种惯用的 Go 信号模式,如果您关闭缓冲 channel ,消费者可以读取所有排队的数据然后停止。

这段代码可以正常工作:

func main() {
messages := make(chan int)
var wg sync.WaitGroup
var result []int

// you can also add these one at
// a time if you need to

wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 1
}()
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 2
}()
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Second * 1)
messages <- 3
}()

// this goroutine added to signal end of data stream
// by closing messages channel
go func() {
wg.Wait()
close(messages)
}()

// if you need this to happen inside a go routine,
// this channel is used for signalling end of the work,
// also another sync.WaitGroup could be used, but for just one
// goroutine, a single channel as a signal makes sense (there is no
// groups)
done := make(chan struct{})
go func() {
defer close(done)
for i := range messages {
fmt.Println(i)
result = append(result, i)
}
}()

<-done
fmt.Println(result)
}

如您所见,我们刚刚添加了另一个 goroutine,用于在所有生产者完成后关闭 messages channel 。

关于具有 sync.WaitGroup 的 Goroutine 在最后一个 wg.Done() 之前结束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43166750/

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