On Tue, Dec 18, 2018 at 5:35 AM Chris Burkert <burkert.ch...@gmail.com> wrote:
>
> I have a couple of goroutines sending multiple results over a channel - a 
> simple fan-in. They signal the completion on a done channel. Main selects on 
> the results and done channel in parallel. As the select is random main 
> sometimes misses to select the last result. What would be the idiomatic way 
> to prevent this and completely drain the result channel?
>
> Here is a minmal example which sometimes prints one 0 but should always print 
> two of them:
>
> package main
>
> import (
>         "fmt"
> )
>
> func do(rc chan<- int, dc chan<- bool) {
>         rc <- 0
>         dc <- true
> }
>
> func main() {
>         worker := 2
>         rc := make(chan int, worker)
>         done := 0
>         dc := make(chan bool, worker)
>         for i := 0; i < worker; i++ {
>                 go do(rc, dc)
>         }
>         for done < worker {
>                 select {
>                 case <-dc:
>                         done++
>                 case r := <-rc:
>                         fmt.Println(r)
>                 }
>         }
> }


I assume the workers can generate multiple results, as otherwise the
done marker seems pointless.  In general the simplest way to signal
completion on a channel is to call close.  The simplest way to call
close on a fan-in is to have another goroutine that waits for the
other goroutines and closes the channel.  That might look like

package main

import (
        "fmt"
        "sync"
)

func do(rc chan<- int) {
        rc <- 0
}

func main() {
        worker := 2
        rc := make(chan int, worker)
        var wg sync.WaitGroup
        wg.Add(worker)
        for i := 0; i < worker; i++ {
                go func() {
                        defer wg.Done()
                        do(rc)
                }()
        }
        go func() {
                wg.Wait()
                close(rc)
        }()
        for r := range rc {
                fmt.Println(r)
        }
}

Ian

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to