[日常] GO语言圣经-并发获取多个URL
go语言圣经-并发获取多个URL
1.GO最新奇的特性就是对并发编程的支持,goroutine和channel
2.goroutine是一种函数的并发执行方式,而channel是用来在goroutine之间进行参数传递
go function则表示创建一个新的goroutine,并在这个新的goroutine中执行这个函数。
3.make函数创建了一个传递string类型参数的channel
4.io.Copy把响应的Body内容拷贝到ioutil.Discard输出流中,扔到一个垃圾桶
5.goroutine尝试在一个channel上做send或者receive操作时,这个goroutine会阻塞在调用处,直到另一个goroutine往这个channel里写入、或者接收值
6.用main函数来接收所有fetch函数传回的字符串,可以避免在goroutine异步执行还没有完成时main函数提前退出。
练习 1.10: 找一个数据量比较大的网站,用本小节中的程序调研网站的缓存策略,对每个URL执行两遍请求,查看两次时间是否有较大的差别,并且每次获取到的响应内容是否一致,修改本节中的程序,将响应结果输出,以便于进行对比。
练习 1.11: 在fetchall中尝试使用长一些的参数列表,比如使用在alexa.com的上百万网站里排名靠前的。如果一个网站没有回应,程序将采取怎样的行为?(Section8.9 描述了在这种情况下的应对机制)。
fetchall.go
package main //导入io/ioutil和net/http包
import (
"fmt"
"io"
"os"
"io/ioutil"
"net/http"
"strings"
"time"
) func main() {
//当前时间
start := time.Now()
//make函数创建了一个传递string类型参数的channel
ch := make(chan string)
//for循环命令行参数
for _, url := range os.Args[1:] {
//开启一个goroutine
go fetch(url,ch)
}
//接收并打印channel,for循环不需要key value
for range os.Args[1:]{
fmt.Printf(<-ch)//注意箭头方向,接收channel
}
//main函数的时间
fmt.Printf("main: %.2fs \n",time.Since(start).Seconds())
}
//参数类型:string , chan<- string
func fetch(url string,ch chan<- string){
start := time.Now()
//加入前缀
if !strings.HasPrefix(url, "http://") {
url = "http://" + url
}
res, err := http.Get(url)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr, "fetch:%v \n", err)
//终止进程
os.Exit(1)
}
//输出http code
//fmt.Printf("\nhttp status code :%s\n", res.Status) //把内容扔掉,只获取字节数
nBytes , err:=io.Copy(ioutil.Discard, res.Body)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr, "fetch:%v \n", err)
//终止进程
os.Exit(1)
}
res.Body.Close()
//记录执行的秒数
sec := time.Since(start).Seconds()
//发送给channel
ch<- fmt.Sprintf("%.2fs %7d %s \n",sec,nBytes,url)
}
对比fetch.go
package main //导入io/ioutil和net/http包
import (
"fmt"
"io"
"os"
"io/ioutil"
"net/http"
"strings"
"time"
) func main() {
//开始时间
start := time.Now()
//for循环命令行参数
for _, url := range os.Args[1:] {
//加入前缀
if !strings.HasPrefix(url, "http://") {
url = "http://" + url
}
res, err := http.Get(url)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr, "fetch:%v \n", err)
//终止进程
os.Exit(1)
} //body,err := ioutil.ReadAll(res.Body)
//避免申请一个缓冲区,直接到标准输出流
nBytes,err:=io.Copy(ioutil.Discard, res.Body)
//判断错误
if err != nil {
//向标准错误流打印信息
fmt.Fprintf(os.Stderr, "fetch:%v \n", err)
//终止进程
os.Exit(1)
}
res.Body.Close()
//输出http code
fmt.Printf("\nhttp status code :%s %7d %s\n", res.Status,nBytes,url)
//fmt.Printf("%s",body)
}
//结束时间
sec:=time.Since(start).Seconds()
fmt.Printf("main:%.2fs\n",sec)
}
执行效果对比:
[日常] GO语言圣经-并发获取多个URL的更多相关文章
- [日常] Go语言圣经-并发的非阻塞缓存
1.go test命令是一个按照约定和组织进行测试的程序2.竞争检查器 go run -race 附带一个运行期对共享变量访问工具的test,出现WARNING: DATA RACE 说明有数据竞争3 ...
- [日常] Go语言圣经--并发的循环习题
练习 8.4: 修改reverb2服务器,在每一个连接中使用sync.WaitGroup来计数活跃的echo goroutine.当计数减为零时,关闭TCP连接的写入,像练习8.3中一样.验证一下你的 ...
- [日常] Go语言圣经--并发的web爬虫
两种: crawler.go package main import ( "fmt" "links" //"log" "os&qu ...
- [日常] Go语言圣经前言
https://books.studygolang.com/gopl-zh/ go语言圣经 1.Go语言有时候被描述为“C类似语言”,或者是“21世纪的C语言”. 2.Go语言中和并发编程相关的特性是 ...
- [日常] Go语言圣经--复合数据类型,数组习题
go语言圣经-复合数据类型 1.以不同的方式组合基本类型可以构造出来的复合数据类型 2.四种类型——数组.slice.map和结构体 3.数组是由同构的元素组成——每个数组元素都是完全相同的类型——结 ...
- [日常] Go语言圣经-WEB服务与习题
Go语言圣经-web服务 1.Web服务程序,标准库里的方法已经帮我们完成了大量工作 2.main函数将所有发送到/路径下的请求和handler函数关联起来,/开头的请求其实就是所有发送到当前站点上的 ...
- [日常] Go语言圣经--接口约定习题
Go语言圣经-接口1.接口类型是对其它类型行为的抽象和概括2.Go语言中接口类型的独特之处在于它是满足隐式实现的3.Go语言中还存在着另外一种类型:接口类型.接口类型是一种抽象的类型4.一个类型可以自 ...
- [日常] Go语言圣经-Panic异常,Recover捕获异常习题
Go语言圣经-Panic异常1.当panic异常发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 机制)2.不是所有的panic异常都来自运行时,直接调用内置的pan ...
- [日常] Go语言圣经-匿名函数习题
Go语言圣经-匿名函数1.拥有函数名的函数只能在包级语法块中被声明,通过函数字面量(function literal),我们可绕过这一限制,在任何表达式中表示一个函数值2.通过这种方式定义的函数可以访 ...
随机推荐
- C# 成员变量和属性的区别
之前一直在C#中使用这两者, 却一直不知道成员变量和属性还是不一样的两种概念. 不过说不一样, 也不是完全对. 简单举个例子: public class myclass { public string ...
- 华为交换机 查看 ip和mac对应关系
IPv4: display arp IPv6: display ipv6 neighbors
- OpenStack kolla 多 region 部署配置
region one: cat /etc/kolla/globals.yml openstack_region_name: "RegionOne" multiple_regions ...
- 2018 Multi-University Training Contest 4
累惹. B. Harvest of Apples 题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6333 题意:求∑(i=0,m) C(n,m). 分 ...
- 在centOS 7 中安装 MySQL
知道来源:https://www.cnblogs.com/bigbrotherer/p/7241845.html 1 下载并安装MySQL官方的 Yum Repository [root@localh ...
- JVM内存参数( -Xms -Xmx -Xmn -Xss 直接内存)
JVM调优总结 -Xms -Xmx -Xmn -Xss jvm 内存 在不同的情况下如何增大 及 PermGen space 相关 JVM日志和参数的理解 JVM崩溃Log日志分析 -Xms 为jvm ...
- RPC理解
RPC,英文名称Remote Procedure Call Protocol,即远程过程通讯协议. 可以设想一种情况,有一个人,叫A,A想要翻开一本书,非常简单,让大脑控制自己两只手,轻易就可以看到书 ...
- LC-BLSTM结构快速解读
参考文献如下: (1) A Context-Sensitive-Chunk BPTT Approach to Training Deep LSTM/BLSTM Recurrent Neural Net ...
- Explorer内存占用偶尔变高导致卡顿
症状: 打开 "这台电脑",加载缓慢.此时查看任务管理器,explorer内存可能飙升到几G.cpu也很高 创建和删除文件缓慢,删除单个文件也会出现进度条.此时查看任务管理器,会出 ...
- Vue的实时时间转换Demo
Vue的实时时间转换Demo time.html: <!DOCTYPE html> <html lang="en"> <head> <me ...