Reading from multiple channels simultaneously in Golang

Jing picture Jing · Dec 15, 2013 · Viewed 26.7k times · Source

I am new to Golang. Right now I am trying to figure out how to make an any-to-one channel in Golang, where the setup is as follows:

say I have two goroutines numgen1 and numgen2 executing concurrently and writing numbers to channels num1 resp. num2. I would like to add the numbers sent from numgen1 and numgen2 in a new process, addnum. I have tried something like this:

func addnum(num1, num2, sum chan int) {
    done := make(chan bool)
    go func() {
        n1 := <- num1
        done <- true
    }()
        n2 := <- num2
        <- done
    sum <- n1 + n2
}

but this seems sadly incorrect. Could someone please give me some ideas?

Thank you very much for your help.

Answer

Rick-777 picture Rick-777 · Dec 16, 2013

Depending on your requirements, you may need to read both of the channels for every iteration (i.e. a sort-of 'zip' function). You can do this with a select, similarly to user860302's answer:

func main() {

  c1 := make(chan int)
  c2 := make(chan int)
  out := make(chan int)

  go func(in1, in2 <-chan int, out chan<- int) {
    for {
      sum := 0
      select {
      case sum = <-in1:
        sum += <-in2

      case sum = <-in2:
        sum += <-in1
      }
      out <- sum
    }
  }(c1, c2, out)
}

This runs forever. My preferred way to terminate goroutines like this one is to close the input channels. In this case you would need to wait for both to close, then close(out) before terminating.

Tip: note the use of directional channels as goroutine formal parameters. The compiler catches more mistakes when you write it this way. Happiness!