使用goroutine与channel实现Go语言并发文件下载,通过WaitGroup等待任务完成,并用带缓冲channel控制最大并发数防止资源耗尽。

在Go语言中实现并发文件下载,核心思路是利用goroutine和channel来并行发起多个HTTP请求,同时控制并发数量防止资源耗尽。通过合理分配任务、合并结果和错误处理,可以高效地完成多个文件的下载。
每个文件下载任务可以在独立的goroutine中执行,使用sync.WaitGroup等待所有任务完成。这种方式简单直接,适合数量不多的并发下载。
示例代码结构:
func downloadFile(url, filename string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
<pre class='brush:php;toolbar:false;'>file, err := os.Create(filename)
if err != nil {
return err
}
defer file.Close()
io.Copy(file, resp.Body)
return nil}
立即学习“go语言免费学习笔记(深入)”;
func main() { urls := []string{"https://www.php.cn/link/18c578f830e2897ac30e2c72e6e122a1", "https://www.php.cn/link/c2e4a009b0acaea484f4384134824c69"} var wg sync.WaitGroup
for i, url := range urls {
wg.Add(1)
go func(u string, idx int) {
defer wg.Done()
err := downloadFile(u, fmt.Sprintf("file_%d", idx))
if err != nil {
log.Printf("下载失败: %s, 错误: %v", u, err)
}
}(url, i)
}
wg.Wait()}
立即学习“go语言免费学习笔记(深入)”;
当下载任务较多时,无限制地启动goroutine可能导致内存或连接数爆炸。可以通过带缓冲的channel作为信号量来控制最大并发数。
常见做法:
semaphore := make(chan struct{}, 10) // 最多10个并发
for i, url := range urls {
go func(u string, idx int) {
semaphore <- struct{}{} // 获取令牌
err := downloadFile(u, fmt.Sprintf("file_%d", idx))
if err != nil {
log.Println("下载出错:", err)
}
<-semaphore // 释放令牌
}(url, i)
}
// 等待所有任务完成(可通过额外channel或time.Sleep简化)
time.Sleep(2 * time.Second)
真实场景中需要对下载任务设置超时机制,避免长时间阻塞。使用context.WithTimeout可统一管理生命周期。
关键点:
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() <p>req, _ := http.NewRequestWithContext(ctx, "GET", url, nil) resp, err := http.DefaultClient.Do(req)</p>
基本上就这些。并发下载的核心是合理调度goroutine,控制资源使用,加上必要的错误和超时处理,就能稳定高效地运行。
以上就是Golang如何实现并发文件下载的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号