[英]How to close a channel with multiple senders?
我有一个案例,我需要扇出发送到同一频道的接收器:
func MessagesFromSQS(ctx context.Context, sqsClient sqsiface.SQSAPI) chan *sqs.Message {
messages := make(chan *sqs.Message)
go func() {
defer close(messages)
wg := sync.WaitGroup{}
for i := 0; i < parallelSQSReaders; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
return
default:
// ...
for _, message := range result.Messages {
messages <- message
}
}
}
}()
}
wg.Wait()
}()
return messages
}
对我来说,这是有道理的。 但是,竞争检测器抱怨不同的 goroutine 以及发送和关闭通道。 我意识到负责发送的 goroutine 应该与关闭的 goroutine 相同,但是正确的方法是什么?
编辑/解决:感谢您的回复。 事实证明我没有正确读取比赛检测器堆栈跟踪。 我假设我更改的代码引入了错误,而不是在 SQS 模拟中发现错误。 一旦我正确同步了ReceiveMessage()
就很好了。
当您知道不会再有任何写入时关闭通道,即当所有工作程序 go-routines 完成时。
所以:
wg.Wait()
close(messages)
PS我会通过将select与您的频道写入组合来重组您对上下文取消的轮询,例如
for _, message := range result.Messages {
select {
case messages <- message:
case <-ctx.Done():
return
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.