Go并发下载需用goroutine处理任务、channel协调状态,并通过带缓冲channel(如sem := make(chan struct{}, 5))实现并发控制,配合WaitGroup确保worker启动完成后再关闭输入channel。

在 Go 中实现并发文件下载,核心是用 goroutine 处理多个下载任务,用 channel 协调状态、传递结果或控制并发数。不加限制地启动成百上千个 goroutine 可能压垮网络或目标服务器,所以需结合 semaphore(信号量)或带缓冲的 channel 实现并发控制。
把待下载的 URL 列表发到一个输入 channel,启动固定数量的工作 goroutine 从该 channel 消费 URL 并执行下载。每个 goroutine 下载完成后,将结果(如文件名、错误)发到输出 channel。主 goroutine 从输出 channel 收集结果,统一处理成功或失败情况。
chan string(URL)或自定义结构体(含 URL、保存路径等)chan DownloadResult,其中 DownloadResult 包含 URL、Filename、Err error
sync.WaitGroup 确保所有 worker 启动完成后再关闭输入 channel最轻量的方式是创建一个容量为 N 的 channel(比如 sem := make(chan struct{}, 5)),每个 goroutine 在开始下载前先向它发送一个占位符(sem ),下载结束后再取出(<code>)。这样最多只有 5 个 goroutine 同时运行。
都有对应 <code>sem ,且 recover 或 defer 中也要释放
acquire(sem) 和 release(sem)
HTTP 下载必须设超时,否则单个卡住会拖慢整个流程。推荐用 http.Client 配合 context.WithTimeout;失败时可简单重试 1–2 次,避免因临时网络抖动导致整体失败。
立即学习“go语言免费学习笔记(深入)”;
os.MkdirAll
io.Copy 流式写入,避免把整个响应体读进内存启动 5 个 worker,从 urls 切片生成输入 channel,收集结果并打印统计:
sem := make(chan struct{}, 5)
results := make(chan DownloadResult, len(urls))
<p>for _, url := range urls {
go func(u string) {
sem <- struct{}{}
defer func() { <-sem }()</p><pre class="brush:php;toolbar:false;"> filename, err := downloadFile(u)
results <- DownloadResult{URL: u, Filename: filename, Err: err}
}(url)}
// 启动收集 goroutine 或在主协程中 range results for i := 0; i ail %s: %v", res.URL, res.Err) } else { log.Printf("done %s → %s", res.URL, res.Filename) } }
以上就是如何在Golang中实现并发文件下载_协程和channel提高效率的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号