max
max

Reputation: 6187

Dead lock in goroutines

can someone give me some insight about this code, Why this get deadlock error in for x:=range c

func main() {
    c:=make(chan int,10)

    for i:=0;i<5;i++{
        go func(chanel chan int,i int){
            println("i",i)
            chanel <- 1
        }(c,i)
    }

    for x:=range c {
        println(x)
    }
    println("Done!")
}

Upvotes: 0

Views: 92

Answers (3)

colm.anseo
colm.anseo

Reputation: 22097

Channel needs to be closed to indicate task is complete.

Coordinate with a sync.WaitGroup:

c := make(chan int, 10)

var wg sync.WaitGroup // here

for i := 0; i < 5; i++ {

    wg.Add(1) // here

    go func(chanel chan int, i int) {
        defer wg.Done()
        println("i", i)
        chanel <- 1
    }(c, i)
}

go func() {
    wg.Wait() // and here
    close(c)
}()

for x := range c {
    println(x)
}
println("Done!")

https://play.golang.org/p/VWcBC2YGLvM

Upvotes: 1

Cl&#233;ment
Cl&#233;ment

Reputation: 804

Because this:

    for x:=range c {
        println(x)
    }

will loop until the channel c closes, which is never done here.

Here is one way you can fix it, using a WaitGroup:

package main

import "sync"

func main() {
    var wg sync.WaitGroup
    c := make(chan int, 10)

    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func(chanel chan int, i int) {
            defer wg.Done()
            println("i", i)
            chanel <- 1
        }(c, i)
    }

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

    for x := range c {
        println(x)
    }
    println("Done!")
}

Try it on Go Playground

Upvotes: 2

Burak Serdar
Burak Serdar

Reputation: 51582

You create five goroutines, each sending an integer value to the channel. Once all those five values are written, there's no other goroutine left that writes to the channel.

The main goroutine reads those five values from the channel. But there are no goroutines that can possibly write the sixth value or close the channel. So, you're deadlocked waiting data from the channel.

Close the channel once all the writes are completed. It should be an interesting exercise to figure out how you can do that with this code.

Upvotes: 2

Related Questions