直接看go语言实战 go语言自学( 二 )


2.在golang入门到项目实战文件夹中创建一个go文件,例如:test.go
3.在test.go中输入如下内容直接看go语言实战:
4.编译执行go run test.go
5.可仅选择编译执行go build test.go,则目录下会多出个exe程序
Go 语言极速入门13 - 实战项目之并发版爬虫爬取器 fetcher 和解析器 parser 与之前相同 , 模型类也不变 。
注意:
见本小节文末分析 。
Q1. 为什么在 scheduler 中每一个将 Request 添加到 chan 的任务都开启一个 Goroutine 来执行?
A:在Go 语言学习9 - Channel一节描述过 , 对于无缓冲的 channel,如果两个 goroutine 没有同时准备好 , 通道会导致先执行发送或接收操作的 goroutine 阻塞等待  , 假设使用s.workerChan - request而不是go func() { s.workerChan - request }(),假设开启了 10 个 Worker Goroutine,这 10 个 goroutine 阻塞在r := -in阻塞等待获取 Request 上,假设 seeds 大于 10,例如 11 , 那么当 Engine 的这个循环执行到底 11 个的时候,将陷入等待
,因为所有的10个 Worker goroutine 此时都可能也处于等待中 , 即 in chan 没有接收方准备好接收数据,所以 engine 作为发送方也要阻塞等待;那么为什么10个 Worker goroutine 都会处于等待中呢?
因为10个 Worker Goroutine 都处理完了请求,并阻塞在out - result ,由于 Engine 阻塞在 “将第11个 Request 发送到 in” 上,所以其无法进行后续的死循环去开启result := -out ,到此为止,相互等待死锁形成?。。ngine 等待 Worker 准备好r := -in,而10个 Worker 等待 Engine 的result := -out。
当使用go func() { s.workerChan - request }()之后,Engine Goroutine 将不再阻塞 , 死锁等待被打破?。。?
Q2. scheduler 方法为何使用指针接收者而不是值接收者?
A:在Go 语言学习5 - 面向接口中我们详细的介绍了什么时候使用指针接收者,什么时候使用值接收者,其中最重要的两条就是 “ 1. 如果要改变接收者内部的属性值,必须使用指针接收者,因为值接收者是对接收者副本的操作;2. 如果 struct 内一个方法是指针接收者,那么其全部方法都是用指针接收者 ”,在 scheduler 中,我们要将外界的 in chan 赋值给 scheduler 的 workChann , 所以需要改变 workChann 的值 , 需要使用指针接收者 。
直接看go语言实战的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于go语言自学、直接看go语言实战的信息别忘了在本站进行查找喔 。

推荐阅读