1 回答
TA贡献1851条经验 获得超5个赞
在您的程序中,您有以下循环遍历 3 个 URL:
for _, u := range urls {
urlCh <- u //later: go generator(u, urlCh)
}
由于 urlCh 是无缓冲的,循环体中的发送操作将不会完成,直到另一个 Goroutine 执行相应的接收操作。
当你有 3 个工作程序 goroutine 时,这没问题。当您将其减少到两个时,这意味着至少有一个 goroutine 需要进展到足够远才能从urlCh.
现在,如果我们查看主体,worker我们可以看到问题:
for {
url := <-urlCh
length, err := getPage(url)
if err == nil {
sizeCh <- fmt.Sprintf("%s has legth %d. worker %d", url, length, id)
} else {
sizeCh <- fmt.Sprintf("Error getting %s: %s. worker %d", url, err, id)
}
}
在成功发送 上的值之前,此循环无法完成sizeCh。由于这个通道也是无缓冲的,所以在另一个 goroutine 准备好从该通道接收值之前不会发生这种情况。
不幸的是,唯一会这样做的 goroutine 是main,它只有在完成将值发送到urlCh. 这样我们就陷入了僵局。
移动发送到urlCh分离够程修复了问题,因为main可以进步,它从读取点sizeCh,即使不是所有的价值已被送往urlCh。
- 1 回答
- 0 关注
- 175 浏览
添加回答
举报