go 语言 chan 工作原理讲清楚
用一个限流的例子
一 ,不加chan
func main() {
// 一共启动 10 个任务
for i := 1; i <= 10; i++ {
// 启动协程执行任务
go func(taskID int) {
fmt.Printf("任务 %d 开始执行\n", taskID)
time.Sleep(2 * time.Second) // 模拟业务耗时
fmt.Printf("任务 %d 执行完毕\n", taskID)
}(i)
}
// 等待所有任务跑完
time.Sleep(3 * time.Second)
fmt.Println("全部任务结束")
}
任务 5 开始执行
任务 1 开始执行
任务 7 开始执行
任务 9 开始执行
任务 2 开始执行
任务 3 开始执行
任务 4 开始执行
任务 6 开始执行
任务 8 开始执行
任务 10 开始执行
任务 10 执行完毕
任务 8 执行完毕
任务 2 执行完毕
任务 9 执行完毕
任务 4 执行完毕
任务 1 执行完毕
任务 7 执行完毕
任务 5 执行完毕
任务 6 执行完毕
任务 3 执行完毕
全部任务结束
二,加chan
package main
import (
"fmt"
"time"
)
func main() {
const maxNum = 5 // 最大并发数:5
limitCh := make(chan struct{}, maxNum)
// 一共启动 10 个任务
for i := 1; i <= 10; i++ {
limitCh <- struct{}{} // 抢占名额,满5个就阻塞
// 启动协程执行任务
go func(taskID int) {
defer func() {
<-limitCh // 任务结束,释放名额
}()
fmt.Printf("任务 %d 开始执行\n", taskID)
time.Sleep(2 * time.Second) // 模拟业务耗时
fmt.Printf("任务 %d 执行完毕\n", taskID)
}(i)
}
// 等待所有任务跑完
time.Sleep(3 * time.Second)
fmt.Println("全部任务结束")
}
任务 2 开始执行
任务 1 开始执行
任务 5 开始执行
任务 4 开始执行
任务 3 开始执行
任务 2 执行完毕
任务 6 开始执行
任务 5 执行完毕
任务 7 开始执行
任务 3 执行完毕
任务 8 开始执行
任务 4 执行完毕
任务 9 开始执行
任务 1 执行完毕
任务 10 开始执行
任务 7 执行完毕
任务 6 执行完毕
任务 8 执行完毕
任务 9 执行完毕
任务 10 执行完毕
全部任务结束

浙公网安备 33010602011771号