I am currently learning concurrency in go. I write a simple Test program to practice goroutines. But whenever i execute this, i Get an error stating fatal error: all goroutines are asleep - deadlock!
I dont know what i did wrong. Does anyone know how i can make this work as intended. Any help will be much appreciated
import (
"fmt"
"sync"
"time"
)
func slow(i int, cha chan int, wg *sync.WaitGroup) {
fmt.Println("HI", i)
time.Sleep(time.Second * 2)
cha <- i * 2
wg.Done()
}
func main() {
var wg sync.WaitGroup
values := make(chan int)
for i := 1; i < 12; i++ {
wg.Add(1)
go slow(i, values, &wg)
}
wg.Wait()
close(values)
}
EDIT: When i try to make the channel to a buffered channel, it works. I dont know how tho
Your current program is not working since there is no consumer for the unbuffered channel. Also, there is no need to use both WaitGroup
and channel
together.
Consider the below example:
func slow(i int, cha chan int) {
fmt.Println("HI", i)
time.Sleep(time.Second * 2)
cha <- i * 2
}
func main() {
values := make(chan int)
defer close(values)
for i := 1; i < 12; i++ {
go slow(i, values)
}
for i := 1; i < 12; i++ {
fmt.Println(<-values)
}
}
This way we can have a sender goroutine and the messages can be consumed in the main function.
If we just want to make sure that all the goroutines completes before main finishes the execution, we can remove the channels like below:
func slow(i int, wg *sync.WaitGroup) {
fmt.Println("HI", i)
time.Sleep(time.Second * 2)
wg.Done()
}
func main() {
var wg sync.WaitGroup
for i := 1; i < 12; i++ {
wg.Add(1)
go slow(i, &wg)
}
wg.Wait()
}
Using buffered channels worked, because pushing messages to channel is no longer blocking until the buffer is filled.