package main
import (
"fmt"
"sync"
)
func push(c chan int,wg sync.WaitGroup) {
for i := 0; i < 5; i++ {
c <- i
}
wg.Done()
}
func pull(c chan int,wg sync.WaitGroup) {
for i := 0; i < 5; i++ {
result,ok := <- c
fmt.Println(result,ok)
}
wg.Done()
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
c := make(chan int)
go push(c,wg)
go pull(c,wg)
wg.Wait()
}
Output:
localhost:src kuankuan$ go run goroutine.go
0 true
1 true
2 true
3 true
4 true
throw: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0x42130100, 0x42130100)
/usr/local/go/src/pkg/runtime/zsema_amd64.c:146 +0x25
sync.(*WaitGroup).Wait(0x42120420, 0x0)
/usr/local/go/src/pkg/sync/waitgroup.go:79 +0xf2
main.main()
/Users/kuankuan/go/src/goroutine.go:31 +0xb9
goroutine 2 [syscall]:
created by runtime.main
/usr/local/go/src/pkg/runtime/proc.c:221
exit status 2
An unbuffered channel is used to perform synchronous communication between goroutines while a buffered channel is used for perform asynchronous communication. An unbuffered channel provides a guarantee that an exchange between two goroutines is performed at the instant the send and receive take place.
A goroutine is a function that executes simultaneously with other goroutines in a program and are lightweight threads managed by Go. A goroutine takes about 2kB of stack space to initialize.
A deadlock happens when a group of goroutines are waiting for each other and none of them is able to proceed. For example: When one goroutine try to receive message from channel. And channel is empty.
The reason why it deadlocks is because structs are passed by value and not by reference.
When you pass the WaitGroup to your functions, you need to pass the pointer and not the value. Otherwise a copy of the WaitGroup will be used.
This is your working example:
package main
import (
"fmt"
"sync"
)
func push(c chan int,wg *sync.WaitGroup) {
for i := 0; i < 5; i++ {
c <- i
}
wg.Done()
}
func pull(c chan int,wg *sync.WaitGroup) {
for i := 0; i < 5; i++ {
result,ok := <- c
fmt.Println(result,ok)
}
wg.Done()
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
c := make(chan int)
go push(c,&wg)
go pull(c,&wg)
wg.Wait()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With