多线程下载,文件数量未知

foreveriuu · · 1672 次点击
我仿照书上的写个一个,有个问题,程序结束后会报fatal error: all goroutines are asleep - deadlock! ` package main import ( "fmt" "time" ) // URLInfo 保留构造下载链接的信息 type URLInfo struct { urltype string page int } func download1(info URLInfo) bool { time.Sleep(time.Second) if info.page < 10 { fmt.Printf("%s%03d.dat downloaded \n", info.urltype, info.page) } else { fmt.Printf("%s%03d.dat download fail \n", info.urltype, info.page) } return (info.page < 10) } func main() { urllist := make(chan []URLInfo) // 预测可能的文件列表,允许重复 undownLinks := make(chan URLInfo) // 待下载文件URLs,不重复 // 初始化下载. go func() { urllist <- []URLInfo{{"AAA", 1}, {"BBB", 1}, {"CCC", 1}} }() // 分配3个goroutines来下载文件 for i := 0; i < 3; i++ { go func() { for ui := range undownLinks { if download1(ui) { urls := []URLInfo{{ui.urltype, ui.page + 1}, {ui.urltype, ui.page + 2}, {ui.urltype, ui.page + 3}} go func() { urllist <- urls }() } } }() } // 通过主goroutine来过滤重复的文件列表,将未下载的文件发送至undownLinks downedLinks := make(map[URLInfo]bool) for list := range urllist { for _, link := range list { if !downedLinks[link] { downedLinks[link] = true undownLinks <- link } } } close(urllist) close(undownLinks) } `
#5
更多评论
stevewang
耶和华是我的牧者,我必不至缺乏。
用channel配合生产者/消费者模式,就可以控制下载的gorountine数目。 大致流程如下: ``` const ( ThreadCount = 3 ) func main() { ch := make(chan string, ThreadCount) var wg sync.WaitGroup for i := 0; i < ThreadCount; i++ { wg.Add(1) go func() { for url := range ch { download(url) } wg.Done() }() } urls := []string{ "http://www.host.com/AAA001.dat", "http://www.host.com/AAA002.dat", //... } // 分派下载任务 for _, url := range urls { ch <- url } close(ch) wg.Wait() } ```
#1
多谢解答。但是下载数量未知如何解决呢?比如AAA是到了AAA247.dat,但是预先不知道数量,只有尝试AAA247.dat下载失败才知道需要结束,其它BBB、CCC也是如此。
#2