簡體   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