首页 > 解决方案 > 在 go 中将多条消息发送到一个频道进行整理

问题描述

我正试图把我的思绪绕过去。我想做一个简单的程序,基本上

  1. 开始一堆 goroutine
  2. 处理消息
  3. 将处理后的结果发送到通道
  4. 让主线程收集这些结果
  5. 关闭。

看起来很简单。我一开始完全没有逻辑。我只是发送一个号码并尝试取回那个号码。

问题:我陷入僵局,我不知道为什么。我想我可能会滥用带有通道的等待组,因为它们是单独工作的,但我不确定如何让主线程阻塞任意数量的启动 go 例程。

package main

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

func main() {
    queue := make(chan int)
    start := time.Now()
    var wg sync.WaitGroup

    for i := 0; i < 10; i += 1 {
        wg.Add(1)
        go count(i, queue, &wg)
    }

    wg.Wait()

    for value := range queue {
        println(value)
    }

    close(queue)

    fmt.Println(time.Now().Sub(start))
    // fmt.Println(summation)
}

func count(number int, queue chan int, wg *sync.WaitGroup) {
    defer wg.Done()

    fmt.Println("Starting ", number)
    queue <- number
    fmt.Println("ending")

}

标签: gochannels

解决方案


你的 goroutines 阻塞,queue <- number因为queue它是一个无缓冲的通道,没有人从它读取,作为wg.Wait.

改为声明queue为缓冲通道。例如:queue := make(chan int, 10)

Go Tour(并发)和后续页面:

默认情况下,发送和接收阻塞,直到对方准备好。这允许 goroutines 在没有显式锁或条件变量的情况下进行同步。

仅当缓冲区已满时才发送到缓冲通道块。当缓冲区为空时接收块。

或者,wg.Waitfor v := range queue循环之后移动。


推荐阅读