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 执行完毕
全部任务结束

posted @ 2026-06-01 17:17  学无边涯  阅读(3)  评论(0)    收藏  举报