Reputation: 183
I am using buffered channel and i get a proper output what i need.
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
type Expert struct {
name string
age int
}
func main() {
fmt.Println("==== GoRoutines ====")
expertChannel := make(chan Expert, 3)
wg.Add(1)
go printHello()
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Wait()
close(expertChannel)
for x := range expertChannel {
fmt.Println("Expert Data :: ", x)
}
}
func printHello() {
for i := 1; i <= 5; i++ {
fmt.Println("This is from PrintHello() Function where i = ", i)
}
defer wg.Done()
}
func addDataToChannel(c chan Expert, name string, age int) {
defer wg.Done()
c <- Expert{
name,
age,
}
}
But when i am using unBuffered channel then i am getting error and that is fatal error: all goroutines are asleep - deadlock! why this happen and how to resolve this?
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
type Expert struct {
name string
age int
}
func main() {
fmt.Println("==== GoRoutines ====")
expertChannel := make(chan Expert)
wg.Add(1)
go printHello()
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Add(1)
go addDataToChannel(expertChannel, "Name", 24)
wg.Wait()
close(expertChannel)
for x := range expertChannel {
fmt.Println("Expert Data :: ", x)
}
}
func printHello() {
for i := 1; i <= 5; i++ {
fmt.Println("This is from PrintHello() Function where i = ", i)
}
defer wg.Done()
}
func addDataToChannel(c chan Expert, name string, age int) {
defer wg.Done()
c <- Expert{
name,
age,
}
}
when we will use buffered channel and when will use unbuffered channel how to identify the use case of both channel category?
Upvotes: 0
Views: 1854
Reputation: 3669
Send and receive over a channel are blocking if buffer is full. And for unbuffered channel since it has no buffer unless the data is read at the other end it will block immediately.
Once you send first data to channel, unless you read there is no space for other routines to send data to channel. So the senders are blocked.
You need to unblock the main routine that is reading from the channel. So that the senders will find space to continue sending data to channel.
Right now wg.Wait() is blocking and not allowing the main routine (for loop) to read from channel. Once it starts reading from channel the blocked senders can also resume and can send further data.
Do wg.Wait() in a concurrent go routine:
go func() {
wg.Wait()
close(expertChannel)
}()
Upvotes: 1