如何在不产生死锁的情况下拥有一个缓冲通道和多个读取器?
问题描述:
FATAL Error All go routines are asleep. Deadlock.
This is what I tried. I am calling wg.Done()
. What is missing?
package main
import (
"fmt"
"strconv"
"sync"
)
func sender(wg *sync.WaitGroup, cs chan int) {
defer wg.Done()
for i := 0; i < 2; i++ {
fmt.Println(i)
cs <- i
}
}
func reciever(wg *sync.WaitGroup, cs chan int) {
x, ok := <-cs
for ok {
fmt.Println("Retrieved" + strconv.Itoa(x))
x, ok = <-cs
if !ok {
wg.Done()
break
}
}
}
func main() {
wg := &sync.WaitGroup{}
cs := make(chan int, 1000)
wg.Add(1)
go sender(wg, cs)
for i := 1; i < 30; i++ {
wg.Add(1)
go reciever(wg, cs)
}
wg.Wait()
close(cs)
}
答
You should to close channel before wg.Wait
.
All your receivers are waiting for data from channel. That's why you have deadlock.
You can close channel at defer
statement of sender
function.
Also you need to wg.Done()
if the first attempt of receiving from channel was unsuccessful (because channel already closed)
答
There are couple of things:
- You need to close the channel once sender is completed.
- In receiver, range over channel
- Don't need to add 1 to wait group and call Done in sender
Please refer to http://play.golang.org/p/vz39RY6WA7