title: Issue with channel / go routine synchronization in Go
body: <p>Here is a small example program with the basic architecture/flow that I am trying to get working.  How do I get all the numbers and "end" messages to print out?  I have tried putting close statements here and there, but it either doesn't work, or I get panics about trying to close an already closed channel...</p>
  
  <pre><code>package main
  
  import (
      "fmt"
      "time"
  )
  
  func main() {
      d := make(chan uint)
  
      go bar(d)
  
      c1 := make(chan uint)
      c2 := make(chan uint)
      c3 := make(chan uint)
  
      go foo(c1, d)
      go foo(c2, d)
      go foo(c3, d)
  
      c1 &lt;- 1
      c2 &lt;- 2
      c3 &lt;- 3
  
      c1 &lt;- 4
      c2 &lt;- 5
      c3 &lt;- 6
  
      c1 &lt;- 7
      c2 &lt;- 8
      c3 &lt;- 9
  }
  
  func foo(c chan uint, d chan uint) {
      fmt.Println("foo start")
  
      for stuff := range c {
          time.Sleep(1)
          d &lt;- stuff * 2
      }
  
      fmt.Println("foo end")
  }
  
  func bar(d chan uint) {
      fmt.Println("bar start")
  
      for stuff := range d {
          fmt.Printf("bar received %d\n", stuff)
      }
  
      fmt.Println("bar end")
  }
  </code></pre>
  
  <p>The output I am getting looks like this.  Notice the last set of numbers and the "end" outputs are missing.</p>
  
  <pre><code>foo start
  bar start
  foo start
  foo start
  bar received 6
  bar received 2
  bar received 4
  bar received 12
  bar received 8
  bar received 10
  </code></pre>
  
  <p>In my actual program, each "foo" function is doing filtering and a bunch of heavy string regexp stuff.  And I need the "bar" function, because it has the job of reordering based on a timestamp, and serializing printing, so output doesn't get interlaced.</p>