Go程序设计语言1.6 并发获取多个URL
Go最令人感兴趣和新颖的特点是支持并发编程。这是一个大话题,第8章和第9章将专门讨论,所以此处只是简单了解一下Go主要的并发机制、goroutine和通道(channel)。
下一个程序fetchall和前一个一样获取URL的内容,但是它并发获取很多URL内容,于是这个进程使用的时间不超过耗时最长时间的获取任务,而不是所有获取任务总的时间。这个版本的fetchall丢弃响应的内容,但是报告每一个响应的大小和花费的时间:
这有一个例子:
goroutine是一个并发执行的函数。通道是一种允许某一例程向另一个例程传递指定类型的值的通信机制。main函数在一个goroutine中执行,然后go语句创建额外的goroutine。
main函数使用make创建一个字符串通道。对于每个命令行参数,go语句在第一轮循环中启动一个新的goroutine,它异步调用fetch来使用http.Get获取URL内容。io.Copy函数读取响应的内容,然后通过写入ioutil.Discard输出流进行丢弃。Copy返回字节数以及出现的任何错误。每一个结果返回时,fetch发送一行汇总信息到通道ch。main中的第二轮循环接收并且输出那些汇总行。
当一个goroutine试图在一个通道上进行发送或接收操作时,它会阻塞,直到另一个goroutine试图进行接收或发送操作才传递值,并开始处理两个goroutine。本例中,每一个fetch在通道ch上发送一个值(ch - expression),main函数接收它们( -ch)。由main来处理所有的输出确保了每个goroutine作为一个整体单元处理,这样就避免了两个goroutine同时完成造成输出交织所带来的风险。
练习1.10:找一个产生大量数据的网站。连续两次运行fetchall,看报告的时间是否会有大的变化,调查缓存情况。每一次获取的内容一样吗?修改fetchall将内容输出到文件,这样可以检查它是否一致。
练习1.11:使用更长的参数列表来尝试fetchall,例如使用alexa.com排名前100万的网站。如果一个网站没有响应,程序的行为是怎样的?(8.9节会通过复制这个例子来描述响应的机制。)
相关文章
- Go/Python/Erlang编程语言对比分析及示例 基于RabbitMQ.Client组件实现RabbitMQ可复用的 ConnectionPool(连接池) 封装一个基于NLog+NLog.Mongo的日志记录工具类LogUtil 分享基于MemoryCache(内存缓存)的缓存工具类,C# B/S 、C/S项目均可以使用!
- Go 切片实现栈
- 《Go并发编程实战》第2版 紧跟Go的1.8版本号
- The "Go" Learning Trip -- 1. Hello Go, Frist “go” Code -- Part1-1
- centos 8.2 配置 go 项目开发环境
- Go Mutex【1】并发编程详解
- go unsafe包使用详解
- go redisgo包基础详解
- go time包详解
- 为什么在Go中我们需要使用Mock测试(附源码)
- Linux有问必答-如何在Linux中安装Go语言
- Go: go module
- Go: go-redis
- go string convert to json quick solution
- 05、GO数组与切片
- 如何删除数组中的某个元素(C/Python/Java/Go/MATLAB)
- Go标准库:深入剖析Go template
- Go Web:HttpRouter路由
- go基础系列:数组
- GO语言练习:第一个Go语言工程--排序
- 初识GO语言——安装Go语言
- 【Go语言入门】一文搞懂Go语言的最新依赖管理:go mod的使用
- 【Go语言入门教程】WaitGroup 实现并发等待
- Go最新版下载 Go1.20版新特性
- 担忧个人隐私漏洞 Pokémon Go对用户访问权限进行升级
- Go语言排序算法实现
- Grumpy:Google 用 Go 开发的 Python 运行时
- Go 迭代切片