假设计算一组大整数的平方和,通过并发分配任务到多个 goroutine,提升计算效率(尤其数据量大时)。
package main
import (
"fmt"
"sync"
)
// 计算单个数字的平方,并将结果发送到通道
func square(num int, resultChan chan int, wg *sync.WaitGroup) {
defer wg.Done() // 任务完成后通知WaitGroup
resultChan <- num * num
}
func main() {
numbers := []int{12345, 67890, 13579, 24680, 98765, 54321} // 待计算的数字
resultChan := make(chan int, len(numbers)) // 带缓冲通道,存储计算结果
var wg sync.WaitGroup
// 1. 启动goroutine并行计算
wg.Add(len(numbers)) // 等待的任务数=数字个数
for _, num := range numbers {
go square(num, resultChan, &wg)
}
// 2. 单独启动goroutine等待所有计算完成后关闭通道
go func() {
wg.Wait()
close(resultChan) // 所有计算完成后关闭通道,避免range阻塞
}()
// 3. 从通道读取结果并累加总和
total := 0
for squareResult := range resultChan {
total += squareResult
}
fmt.Printf("所有数字的平方和:%d
", total)
}所有数字的平方和:18260239032模拟从多个 URL 下载文件,通过并发下载提升整体效率(网络 IO 操作适合并发)。
package main
import (
"fmt"
"io"
"net/http"
"os"
"path/filepath"
"sync"
"time"
)
// 下载单个文件
func downloadFile(url string, saveDir string, wg *sync.WaitGroup, errChan chan error) {
defer wg.Done()
// 1. 创建保存目录(若不存在)
if err := os.MkdirAll(saveDir, 0755); err != nil {
errChan <- fmt.Errorf("创建目录失败:%w", err)
return
}
// 2. 发送HTTP请求
startTime := time.Now()
resp, err := http.Get(url)
if err != nil {
errChan <- fmt.Errorf("请求%s失败:%w", url, err)
return
}
defer resp.Body.Close()
// 3. 检查响应状态
if resp.StatusCode != http.StatusOK {
errChan <- fmt.Errorf("下载%s失败,状态码:%d", url, resp.StatusCode)
return
}
// 4. 创建本地文件
filename := filepath.Base(url) // 从URL提取文件名
savePath := filepath.Join(saveDir, filename)
file, err := os.Create(savePath)
if err != nil {
errChan <- fmt.Errorf("创建文件%s失败:%w", savePath, err)
return
}
defer file.Close()
// 5. 写入文件内容
_, err = io.Copy(file, resp.Body)
if err != nil {
errChan <- fmt.Errorf("写入文件%s失败:%w", savePath, err)
return
}
// 6. 下载成功
duration := time.Since(startTime)
fmt.Printf("✅ 成功下载:%s → %s(耗时:%v)
", url, savePath, duration)
}
func main() {
// 待下载的文件URL列表
urls := []string{
"https://golang.org/lib/godoc/images/footer-gopher.jpg",
"https://www.runoob.com/wp-content/uploads/2019/09/go-logo.png",
"https://www.baidu.com/img/flexible/logo/pc/result.png",
}
saveDir := "./downloads" // 保存目录
var wg sync.WaitGroup
errChan := make(chan error, len(urls)) // 收集错误信息
// 1. 启动goroutine并发下载
wg.Add(len(urls))
for _, url := range urls {
go downloadFile(url, saveDir, &wg, errChan)
}
// 2. 等待所有下载任务完成后关闭错误通道
go func() {
wg.Wait()
close(errChan)
}()
// 3. 处理错误信息
for err := range errChan {
if err != nil {
fmt.Printf("❌ 下载错误:%v
", err)
}
}
fmt.Println("所有下载任务已完成")
}维度 | 并行计算案例 | 多任务下载案例 |
任务类型 | CPU 密集型(计算为主) | IO 密集型(网络请求为主) |
性能瓶颈 | CPU 处理能力 | 网络带宽 / 远程服务器响应速度 |
并发度提议 | 不宜超过 CPU 核心数(避免频繁切换) | 可适当提高(IO 等待时不占用 CPU) |
通道作用 | 传递计算结果 | 传递错误信息 |
通过这两个案例可看出,Go 的并发模型(goroutine + channel + 同步工具)能简洁高效地实现并行任务处理,无论是计算密集型还是 IO 密集型场景都能很好适配。