GoLang channel管道

🎯 一、channel 学习全景图

你可以把 channel 学成这 5 层:

复制代码
基础语法 → 使用模式 → 并发控制 → 底层原理 → 实战设计

🧠 二、第一层:基础语法(必须熟练)

1️⃣ 创建

复制代码
ch := make(chan int)        // 无缓冲
ch := make(chan int, 10)    // 有缓冲

2️⃣ 发送 / 接收

复制代码
ch <- 1      // 发送
x := <-ch    // 接收

3️⃣ 关闭

复制代码
close(ch)

4️⃣ 判断关闭

复制代码
v, ok := <-ch

5️⃣ range

复制代码
for v := range ch {
    fmt.Println(v)
}

👉 重点:必须 close,否则死循环


⚙️ 三、第二层:核心特性(必须理解)


1️⃣ 阻塞机制(最重要)

👉 channel 的本质是:同步机制

无缓冲 channel

复制代码
ch := make(chan int)

go func() {
    ch <- 1
}()

<-ch

👉 发送必须等接收


有缓冲 channel

复制代码
ch := make(chan int, 2)

👉 不满不阻塞


2️⃣ FIFO(先进先出)

👉 channel 内部是队列


3️⃣ 单向 channel(面试加分)

复制代码
func send(ch chan<- int)
func recv(ch <-chan int)

👉 限制方向,提高安全性


🔄 四、第三层:select 多路复用(重点)

复制代码
select {
case v := <-ch1:
    fmt.Println(v)
case ch2 <- 10:
    fmt.Println("send")
default:
    fmt.Println("no ready")
}

🔥 关键点

  • 随机选择一个可执行 case

  • 没有 ready:

    • 有 default → 执行 default

    • 没 default → 阻塞


⏱ 超时控制

复制代码
select {
case <-ch:
case <-time.After(time.Second):
    fmt.Println("timeout")
}

🚀 五、第四层:常见使用模式(非常重要)


1️⃣ 生产者-消费者

复制代码
ch := make(chan int, 10)

go func() {
    for i := 0; i < 10; i++ {
        ch <- i
    }
    close(ch)
}()

for v := range ch {
    fmt.Println(v)
}

2️⃣ worker pool(面试高频)

复制代码
jobs := make(chan int, 100)

for i := 0; i < 5; i++ {
    go func() {
        for job := range jobs {
            fmt.Println(job)
        }
    }()
}

3️⃣ fan-in(合并多个 channel)

复制代码
func fanIn(ch1, ch2 <-chan int) <-chan int

4️⃣ fan-out(广播)

👉 一个 channel → 多个 worker


5️⃣ 通知模式

复制代码
done := make(chan struct{})

👉 用于结束 goroutine


🧠 六、第五层:底层原理(面试高频)


📦 channel 本质结构

复制代码
type hchan struct {
    buf      // 环形队列
    sendq    // 发送等待队列
    recvq    // 接收等待队列
    lock     // 互斥锁
}

📤 发送流程

  1. 有接收者 → 直接交付

  2. 有缓冲 → 放入 buffer

  3. 满了 → 阻塞(进入 sendq)


📥 接收流程

  1. 有数据 → 直接取

  2. 有发送者 → 直接拿

  3. 没数据 → 阻塞(进入 recvq)


🔐 为什么线程安全?

👉 因为:

  • 内部加锁

  • 调度器控制 goroutine


⚠️ 七、常见问题(必须掌握)


❌ 死锁

复制代码
ch := make(chan int)
ch <- 1 // 没人接收

❌ goroutine 泄漏

复制代码
go func() {
    <-ch // 永远阻塞
}()

❌ close 使用错误

复制代码
close(ch)
close(ch) // panic

❌ 向已关闭 channel 发送

👉 直接 panic


⚔️ 八、channel vs mutex(面试必问)

对比 channel mutex
用途 通信 共享数据
安全性 需手动控制
性能 稍低 更快

👉 结论:

简单共享用锁,复杂协作用 channel


🧩 九、学习路径(你可以照着练)

第1步(1天)

  • 基本语法

  • 阻塞理解


第2步(2天)

  • select

  • timeout


第3步(3天)

  • worker pool

  • producer-consumer


第4步(进阶)

  • goroutine 泄漏

  • context + channel


🔥 十、终极总结(面试王炸)

👉 你可以这样说:

channel 是 Go 提供的 goroutine 通信机制,支持同步和异步传输,通过阻塞保证并发安全,底层由环形队列和等待队列实现,常用于任务调度、并发控制和数据流处理。

相关推荐
RSTJ_16251 分钟前
PYTHON+AI LLM DAY SIXTY-ONE
开发语言·python
zfoo-framework4 分钟前
理解kotlin limitedParallelism(1)与Actor模型
android·开发语言·kotlin
Generalzy4 分钟前
从本地 Demo 到生产级检索:Milvus 学习笔记(1)
golang·prompt·软件工程
.千余13 分钟前
【C++】C++类与对象3:const成员函数与取地址运算符重载,权限管理的艺术
开发语言·c++
影寂ldy15 分钟前
C# 类和对象
开发语言·c#
丷丩18 分钟前
MapLibre GL JS第25课:添加栅格瓦片源
开发语言·javascript·gis·mapbox·maplibre gl js
go不是csgo20 分钟前
GORM 上手:一个 main.go 跑通 Go 数据库增删改查
jvm·数据库·golang
她的男孩25 分钟前
从自然语言到数据大屏:Forge Report Studio 的 AI 生成链路
人工智能·后端·架构
她的男孩30 分钟前
大屏动态数据接入:从静态 Mock 到真实业务 API
后端·架构
朔北之忘 Clancy1 小时前
2026 年 3 月青少年软编等考 C 语言二级真题解析
c语言·开发语言·c++·学习·青少年编程·题解·考级