Golang通过Goroutine+Channel指定同时下载的数量


声明:本文转载自https://my.oschina.net/90design/blog/1607131,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

What you are wasting today is tomorrow for those who died yesterday; what you hate now is the future you can not go back.

你所浪费的今天是昨天死去的人奢望的明天; 你所厌恶的现在是未来的你回不去的曾经。

 今天发现某盘里有好多收藏的歌曲,于是想下载下来,就想用Golang下一个(别问为啥)

下载部分整理为库, 代码如下:

package download  import ( 	"strconv" 	"sync" 	"time" )  type Urls struct { 	Urls []string 	Wg   sync.WaitGroup 	Chs  chan int  // 默认下载量 	Ans  chan bool // 每个进程的下载状态 }  // 初始化下载地址  根据项目确认使用配置文件的方式还是其他方式,此处使用爬虫处理没公开 func (u *Urls) InitUrl(end chan bool) { 	for i := 0; i < 20; i++ { 		u.Urls = append(u.Urls, "https://studygolang.com/articles/2228") 	} 	end <- true }  // 实际的下载操作 func downloadHandle(url string, b *bar.Bar) string {     //需要根据下载内容作存储等处理 	time.Sleep(3*time.Second) 	return "" }  /** 每个线程的操作 url 下载地址 chs 默认下载量 ans 每个线程的下载状态 */ func (u *Urls) Work(url string) { 	defer func() { 		<-u.Chs  // 某个任务下载完成,让出 		u.Wg.Done() 	}()     downloadHandle(url) 	u.Ans <- true // 告知下载完成 } 

调用方式:

package main  import ( 	dl "downloadAndstup/download" ) func main(){ 	end := make(chan bool) 	u := dl.Urls{ 		Chs:make(chan int , 5), // 默认同时下载5个 		Ans: make(chan bool), 	} 	// 初始化url 	go u.InitUrl(end) 	if  ok := <- end; ok{        // 分发的下载线程 		go func(){ 			for _, v := range u.Urls{ 				u.Chs <- 1 // 限制线程数 (每次下载缓存加1, 直到加满阻塞) 				u.Wg.Add(1) 				go u.Work(v) 			}             u.Wg.Wait() // 等待所有分发出去的线程结束 			close(u.Ans)// 否则range 会报错哦 		}()                // 静静的等待每个下载完成 		for  _ = range u.Ans{ 		} 	}  }

以上的线程会在某一个下载任务完成后,马上启动一新goroutine继续共5个下载的任务,

如果新需求是同时下载,并且按循序下载5个后,再启动新5个下载任务?后续更新

 

 

 

本文发表于2018年01月15日 12:35
(c)注:本文转载自https://my.oschina.net/90design/blog/1607131,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 9224 讨论 125 喜欢 1

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1