繁体   English   中英

如何关闭具有多个发件人的频道?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM