进入例行程序,出现通道死锁

I just started to learn Go so please bear with me, I've tried to play around with Go routines and channels but are getting a deadlock somehow.

Here's the example

package main

import (
    "fmt"
    "sync"
)


func main() {
    total := 2
    var wg sync.WaitGroup
    wg.Add(total)

    ch := make(chan int)

    for idx := 0; idx < total; idx++ {
        fmt.Printf("Processing idx %d
", idx)

        go func(idx int) {
            defer wg.Done()
            ch <- idx
        }(idx)
    }

    for val := range ch {
        fmt.Println(val)
    }

    fmt.Println("Wait")
    wg.Wait()
}

which throws the error

Processing idx 0
Processing idx 1
1
0
fatal error: all goroutines are asleep - deadlock!

range ch reads from the channel until it is closed.

How many times do you call close(ch)? When will the for val := range ch loop terminate?


When should you close the channel? You have a lot of options here, but one way to do it is to add another goroutine:

go func() {
    wg.Wait()
    close(ch)
}()

e.g., after spinning off all routines that will write-to-channel-then-call-wg.Done(), so that the channel is closed once all the writers are done writing. (You can run this goroutine as soon as you've increased the wg count to account for all writers.)