【发布时间】:2015-07-09 22:43:54
【问题描述】:
我有一个无缓冲通道,i 数量的工作人员从(文件系统路径)获取值并处理它(通过 HTTP 发送文件内容)。当我增加i时遇到问题。
当我运行这个时:
paths := make(chan string)
for i := 0; i < 5; i++ {
go func() {
for path := range paths {
fmt.Println(path)
}
}()
}
walkFn := func(path string, info os.FileInfo, err error) error {
if !info.IsDir() {
paths <- path
}
return nil
}
filepath.Walk("/tmp/foo", walkFn)
close(paths)
它按预期工作并输出/tmp/foo的所有内容:
/tmp/foo/2
/tmp/foo/file9
/tmp/foo/file91
/tmp/foo/file90
/tmp/foo/file900
/tmp/foo/file901
/tmp/foo/file902
/tmp/foo/file92
/tmp/foo/file97
/tmp/foo/file93
/tmp/foo/file94
/tmp/foo/file95
/tmp/foo/file96
/tmp/foo/file98
/tmp/foo/file99
但是当我通过 HTTP 发送文件内容时,受影响的文件数量突然下降:
for i := 0; i < 5; i++ {
go func() {
for path := range paths {
resp, err := http.Head("https://example.com/" + strings.TrimPrefix(path, rootDir+"/"))
if err != nil {
fmt.Printf("Error: %s\n", err)
return
}
fmt.Printf("%s: %s\n", path, resp.Status)
}
}()
}
受影响文件的数量从 15 个(即目录中存在的数量)减少到 10 个:
/tmp/foo/2: 404 Not Found
/tmp/foo/file901: 404 Not Found
/tmp/foo/file900: 404 Not Found
/tmp/foo/file9: 404 Not Found
/tmp/foo/file90: 404 Not Found
/tmp/foo/file902: 404 Not Found
/tmp/foo/file91: 404 Not Found
/tmp/foo/file92: 404 Not Found
/tmp/foo/file93: 404 Not Found
/tmp/foo/file94: 404 Not Found
这是一个将i 的值与输出行数相关联的表格:
+-----+-------+
| `i` | lines |
+-----+-------+
| 1 | 15 |
| 5 | 10 |
| 6 | 9 |
| 15 | 0 |
+-----+-------+
为什么会发生这种情况?如何同时处理所有频道条目? http 请求有问题吗?
【问题讨论】:
-
您的工人
return(停止工作)出错。会不会是他们迟早都会遇到错误,没有工人活着的问题?此外,您的程序是否阻止给工作人员足够的时间来完成或在所有工作完成之前退出主程序? -
嗯,但是如果每个工人都死于
return声明,那么您肯定会在输出中看到Error:吗?关于程序块何时退出,我认为它会在paths频道为空时自动完成 - 不是吗?
标签: concurrency go