package main
import (
"fmt"
"io"
"net/http"
"os"
"time"
)
func main() {
urls := []string{
"http://example.com",
"http://golang.org",
"http://github.com",
}
resultCh := make(chan Result)
defer close(resultCh)
for _, url := range urls {
go func(u string) {
var res Result
res.URL = u
resp, err := http.Get(u)
if err != nil {
res.Err = err
resultCh <- res
return
}
defer resp.Body.Close()
_, err = io.Copy(os.Stdout, resp.Body)
if err != nil {
res.Err = err
}
resultCh <- res
}(url)
}
numCompleted := 0
for i := 0; i < len(urls); i++ {
res := <-resultCh
if res.Err != nil {
fmt.Printf("Error for %s: %v\n", res.URL, res.Err)
} else {
fmt.Printf("Successfully processed %s\n", res.URL)
}
numCompleted++
if numCompleted == len(urls) {
fmt.Println("All operations completed.")
}
}
}
type Result struct {
URL string
Err error
}
代码说明
- 定义
Result
结构体:用于存储每个I/O操作的结果和可能出现的错误。
- 创建
resultCh
通道:用于接收每个I/O操作的结果。
- 启动多个goroutine进行I/O操作:这里以HTTP请求为例,实际应用中可以替换为文件读取等其他I/O操作。每个goroutine执行I/O操作,并将结果发送到
resultCh
通道。
- 处理结果:在主goroutine中通过
for
循环从resultCh
通道接收结果,哪个操作先完成,其结果就会先被接收并处理。如果出现错误,打印错误信息;如果成功,打印成功信息。
- 检查所有操作是否完成:通过
numCompleted
变量记录已完成的操作数量,当所有操作完成后,打印提示信息。