go - 使用 chan 和 sync.waitgroup 时的死锁
问题描述
我目前正在学习并发。我编写了一个简单的测试程序来练习 goroutines。但是每当我执行此操作时,我都会收到一条错误消息,指出fatal error: all goroutines are asleep - deadlock!
我不知道我做错了什么。有谁知道我如何使这项工作按预期进行。任何帮助都感激不尽
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)
}
编辑:当我尝试将通道设置为缓冲通道时,它可以工作。我不知道怎么
解决方案
您当前的程序无法运行,因为无缓冲通道没有消费者。此外,没有必要同时使用WaitGroup
两者channel
。
考虑下面的例子:
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)
}
}
这样我们就可以有一个发送者 goroutine,并且可以在主函数中使用消息。
如果我们只是想确保所有的 goroutine 在 main 完成执行之前完成,我们可以像下面这样删除通道:
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()
}
使用缓冲通道有效,因为在缓冲区填满之前将消息推送到通道不再阻塞。
推荐阅读
- reactjs - 在非箭头函数内调用 this.setState?
- .net - 如何访问 XSDocument 元素?
- apache - 为什么 HTTP/2 会为 404 之类的状态代码显示不同类型的标头
- react-native - React Native - 使用返回处理程序时的堆栈导航
- php - 选择不显示字符串值,只显示整数
- ssl - 将 SSL 与 ejabberd 一起使用
- python-2.7 - 如果默认值或给定值,则 ArgParse 参数错误无
- c# - 如何在 C# 中获取蓝牙设备的 OutGoing ComPort
- sql - SQL - 按年细分薪酬时间跨度 fpr 员工
- html - 如何从列表组项目中删除项目符号