- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
第
Golang多线程爬虫高效抓取大量数据的利器
目录前言goroutine(Go协程)channel(通道)channel的初始化channel的关闭waitGroup的使用爬虫爬虫配置爬虫数据开启并行爬取某个链接爬取某个链接的电影数据main函数开启爬虫总结
前言
Golang是一种并发友好的语言,使用goroutines和channels可以轻松地实现多线程爬虫。具体地说,实现的是多协程。协程是一种比线程更轻量化的最小逻辑可运行单位,它不受操作系统调度,由用户调度。因此对于协程并发的控制,有较高的要求。
goroutine(Go协程)
Go协程(Goroutine)是与其他函数同时运行的函数。可以认为Go协程是轻量级的线程,由Go运行时来管理。在函数调用前加上go关键字,这次调用就会在一个新的goroutine中并发执行。当被调用的函数返回时,这个goroutine也自动结束。
比如:
funcson(){
for{
fmt.Printf(sonsays:hello,world!\n)
time.Sleep(time.Second)
funcfather(){
goson()
for{
fmt.Printf(fathersays:你好,世界!\n)
time.Sleep(time.Second)
funcmain(){
father()
}
运行结果:
fathersays:你好,世界!
sonsays:hello,world!
sonsays:hello,world!
fathersays:你好,世界!
fathersays:你好,世界!
sonsays:hello,world!
在这个例子中,main()函数里面执行father(),而father()中又开启了一个协程son(),之后两个死循环分别执行。
当然,如果主协程运行结束时子协程还没结束,那么就会被kill掉。需要注意的是,如果这个函数有返回值,那么这个返回值会被丢弃。
funcmain(){
goloop()
fmt.Println(hello,world!)
funcloop(){
fori:=0;i10000;i++{
fmt.Println(i)
}
运行结果:
hello,world!
0
1
可以看到,子协程刚打印了0、1之后main()函数就结束了,这显然不符合我们的预期。我们有多种方法来解决这个问题。比如在主协程里面sleep(),或者使用channel、waitGroup等。
Go协程(Goroutine)之间通过信道(channel)进行通信,简单的说就是多个协程之间通信的管道。信道可以防止多个协程访问共享内存时发生资源争抢的问题。Go中的channel是goroutine之间的通信机制。这就是为什么我们之前说过Go实现并发的方式是:不是通过共享内存通信,而是通过通信共享内存。
比如:
var(
myMap=make(map[int]int,10)
//计算n!并放入到map里
funcoperation(nint){
res:=1
fori:=1;ii++{
res*=i
myMap[n]=res
funcTest3(){
//我们开启多个协程去完成这个任务
fori:=1;i=200;i++{
gooperation(i)
time.Sleep(time.Second*10)
fmt.Println(myMap)
funcmain(){
Test3()
}
运行结果:
fatalerror:concurrentmapwrites
goroutine42[running]:
这里产生了一个fatalerror,因为我们创建的myMap不支持同时访问,这有点像Java里面的非线程安全概念。因此我们需要一种线程安全的数据结构,就是Go中的channel。
channel(通道)
channel分为无缓冲和有缓冲的。无缓冲是同步的,例如make(chanint),就是一个送信人去你家门口送信,你不在家他不走,你一定要接下信,他才会走
文档评论(0)