← Backend / Go / 基础专题

23_channel与取消

通过通道传值,理解关闭、缓冲和取消信号。

Go 基础专题 23:channel、select 与取消

学习目标:通过通道传值,理解关闭、缓冲和取消信号。

核心知识

make(chan int) 创建无缓冲通道,发送和接收需同步配对;make(chan int, 2) 可暂存两个值。ch <- value 发送,value := <-ch 接收。关闭通道表示后续不会再发送,通常由发送方关闭;接收方可用 for value := range ch 读到关闭为止。

package main

import "fmt"

func main() {
    numbers := make(chan int)
    go func() {
        defer close(numbers)
        for i := 1; i <= 3; i++ { numbers <- i }
    }()
    for number := range numbers { fmt.Println(number) }
}

向已关闭通道发送会 panic;从已关闭且排空的通道接收会立即得到零值和 ok=false。select 在多个可用通信操作间选择,可配合 context.Context 的 Done() 实现超时或取消。取消应沿调用链传播,长时间阻塞的发送和接收也需考虑退出条件。

不要为所有函数都创建 channel。普通函数调用和互斥锁有时更简单。选择并发模型时先写清“谁生产、谁消费、谁关闭、何时退出”。

逐步理解

无缓冲通道的发送会等待接收者;若同一 goroutine 先发送再接收,就会死锁。缓冲通道容量满时发送也会阻塞。关闭后接收者仍能读完缓冲内容,再得到 ok=false。设计时写出谁关闭通道:一般由唯一发送者关闭,接收者不应猜测何时可以关闭。

动手练习

练习:把上述发送范围改成 1 到 5,接收端求和。答案:总和为 15。