2 回答
TA贡献1830条经验 获得超3个赞
该walker通道是无缓冲的。在发送方和接收方准备就绪之前,无缓冲通道上的通信不会继续进行。
死锁是这样的:主 goroutine 通过调用 wg.Done() 等待 walker goroutine 完成。walker goroutine 等待主 goroutine 在通道上接收。
通过删除与等待组相关的所有代码来修复程序。不需要等待组。在主 goroutine 中的通道范围不会完成,直到通道被 walker goroutine 关闭。在步行完成之前,walker goroutine 不会关闭通道。不需要其他协调。
您还可以通过删除 goroutine 和通道来修复代码:
err := filepath.Walk(srcFolder, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
// Insert body of for path := range walker here ...
fmt.Println(path)
return nil
})
if err != nil {
log.Fatal(err)
}
另一种选择是创建一个容量大于将要遍历的文件数量的缓冲通道,但这需要提前知道文件数量,并且与在切片中收集文件名相比没有任何好处。
TA贡献1833条经验 获得超4个赞
如所写(和所示),在运行循环之前绝对不能调用。您可以(但不需要)在循环终止时调用。您根本不需要该变量。wg.Wait()
for path := range walker
wg.Wait()
wg
你的评论说:
// THE GO routine above needs to have finished by the time this for loop // ranges over the channel
但是循环中没有任何东西for
要求函数完成,并且有一些东西(这里的总体策略)要求 goroutine不能在 send 中被阻塞,因为for
只有当发送者(goroutine)时循环才会完成。关闭通道。
- 2 回答
- 0 关注
- 143 浏览
添加回答
举报