英文:
How can I have one buffered channel and multiple readers without producing a deadlock?
问题
> 致命错误 所有的Go协程都处于休眠状态。死锁。
这是我尝试的代码。我调用了wg.Done()
。缺少了什么?
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)
}
英文:
> 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)
}
答案1
得分: 1
在wg.Wait
之前,你应该关闭通道。
你所有的接收器都在等待通道中的数据。这就是为什么会出现死锁的原因。
你可以在sender
函数的defer
语句中关闭通道。
此外,如果从通道接收的第一次尝试不成功(因为通道已关闭),你需要调用wg.Done()
。
英文:
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)
答案2
得分: 0
有几件事情需要注意:
- 发送者完成后需要关闭通道。
- 在接收者中,使用 range 遍历通道。
- 不需要在等待组中添加 1,并在发送者中调用 Done。
请参考 http://play.golang.org/p/vz39RY6WA7。
英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论