How to wait for goroutines to finish and read the channel without a lock?

Issue

I went through a number of examples and questions here on SO, but still can’t get a rather simple code working as expected:

func main() {
    ch := make(chan string)
    var wg sync.WaitGroup
    wg.Add(2)
    go readFile("A", ch, wg)
    go readFile("B", ch, wg)
    go func() {
        wg.Wait()
        close(ch)
    }()
    printer(ch)
}

func readFile(name string, ch chan string, wg sync.WaitGroup) {
    file, err := os.Open(name)
    if err != nil {
        fmt.Errorf("was not able to read from file %s: %s", name, err)
    }
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
        ch <- scanner.Text()
    }
    wg.Done()
}

func printer(ch chan string) {
    for val := range ch {
        fmt.Println(val)
    }
}

So I’m reading from two files, pushing read lines into a channel and then simply print them out (some code was simplified from unneeded detailes)

Two goroutines, WaitGroup for both of them, reparate goroutine with Wait and close channel.

From mine point of view this is pretty much identical to this question and the exepted answer: Let golang close used channel after all goroutines finished

So what’s wrong in my case?

Solution

Start by following the documentation for the sync.WaitGroup instructions:

Package sync

import "sync"

type WaitGroup

A WaitGroup waits for a collection of goroutines to finish. The main
goroutine calls Add to set the number of goroutines to wait for. Then
each of the goroutines runs and calls Done when finished. At the same
time, Wait can be used to block until all goroutines have finished.

A WaitGroup must not be copied after first use.


A WaitGroup must not be copied after first use.

Answered By – peterSO

Answer Checked By – Marie Seifert (GoLangFix Admin)

Leave a Reply

Your email address will not be published.