package main
import (
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"time"
)
func main(){
start:=time.Now()
ch:=make(chan string)
//启动多个协程后台处理
for _,url := range os.Args[1:]{
go fetch(url,ch)
}
//这个循环不会提前执行完,因为上边的循环每次都会往chan里写入
for range os.Args[1:]{
fmt.Println(<-ch)
}
fmt.Printf("%.2f elapsed\n",time.Since(start).Seconds())
}
func fetch(url string, ch chan <-string){
start:=time.Now()
resp,err:=http.Get(url)
if err!=nil{
ch <- fmt.Sprint(err)
return
}
nbytes,err:=io.Copy(ioutil.Discard,resp.Body)
resp.Body.Close()
if err!=nil{
ch <- fmt.Sprintf("while reding %s:%v",url,err)
return
}
secs:=time.Since(start).Seconds()
ch <-fmt.Sprintf("%.2fs %7d %s",secs,nbytes,url)
}
goroutine是一种函数的并发执行方式,而channel是用来在goroutine之间进行参数传递。main函数本身也运行在一个goroutine中,而go function则表示创建一个新的goroutine,并在这个新的goroutine中执行这个函数
当一个goroutine尝试在一个channel上做send或者receive操作时,这个goroutine会阻塞在调用处,直到另一个goroutine往这个channel里写入或者接收值,这样两个goroutine才会继续执行channel操作之后的逻辑。在这个例子中,每一个fetch函数在执行时都会往channel里发送一个值,主函数负责接收这些值。这个程序中我们用main函数来接收所有fetch函数传回的字符串,可以避免在goroutine异步执行完还没有完成main函数提前退出
有疑问加站长微信联系(非本文作者)