跳转到主要内容
模块 7 · 第 2 课(共 5)课程中的32/50~15 min
模块课程(2/5)

渠道:类型化沟通

通道是之间通信的惯用机制 协程。 Go 哲学 (Rob Pike):

“不要通过共享内存来交流;通过交流来共享内存。”

通道是一个类型化的 FIFO 队列,类型安全并且对于并发来说是安全的 使用。与 go 结合,它是 Go 的主要构建块 并发。

创建、发送、接收

Go
ch := make(chan int)     // canale di int, unbuffered

go func() {
    ch <- 42             // invia (può bloccare)
}()

v := <-ch                // ricevi (può bloccare)
fmt.Println(v)           // 42

句法:

  • make(chan T) 或 make(chan T, N) 用于缓冲。
  • ch <- v 发送。
  • v := <-ch 接收。
  • v, ok := <-ch 接收带有标志(ok = false 如果通道关闭且为空)。

无缓冲:会合

无缓冲通道(容量 0)阻塞:

  • 发送者,直到接收者准备好;
  • 接收方,直到发送方准备就绪。

这是一个同步约会:用作“信号”或保证 价值已经交付。

缓冲:队列最多为 N

Go
ch := make(chan int, 3)
ch <- 1   // non blocca
ch <- 2   // non blocca
ch <- 3   // non blocca
ch <- 4   // BLOCCA: il buffer è pieno

仅当缓冲区已满时发送方才会阻塞;仅接收器 当它是空的时候。

近距离和远距离

当没有更多值时,发送者关闭通道:

Go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for v := range ch {      // termina quando ch è chiuso E vuoto
    fmt.Println(v)
}

for range 在通道上迭代,直到通道关闭(并排空)。 这是“消耗所有到达的东西”的最干净的模式。

签名的方向性

函数参数可以限制方向:

Go
func producer(out chan<- int) {   // solo invio
    out <- 1
    close(out)
}

func consumer(in <-chan int) {    // solo ricezione
    for v := range in {
        fmt.Println(v)
    }
}

chan<- T = 仅发送,<-chan T = 仅接收。双向 通道 chan T 可以传递给任一通道(隐式转换)。它 提高清晰度并防止错误。

常见模式(预览)

  • 工作池:N 个 goroutine 从 jobs <-chan T 消费,在 results chan<- R 生产。
  • 管道:通过通道连接的阶段。
  • 完成信号:chan struct{} 通道关闭以发出“停止”信号。
Go
done := make(chan struct{})
go func() {
    <-done    // blocca finché qualcuno chiude done
    cleanup()
}()
close(done)   // segnale di stop

chan struct{} 是“信号”通道:零字节的有效负载,只是 同步。

尝试一下

锻炼#go.m7.l2.e1
尝试:0加载中...

创建一个无缓冲的 int 通道 ch,从 goroutine 发送 42,在 main 中接收并打印它。

正在加载编辑器...
显示提示

如果没有缓冲区,发送方和接收方将同步。

3 次尝试后可用的解决方案

锻炼#go.m7.l2.e2
尝试:0加载中...

通过缓冲通道发送 1,2,3,关闭它,然后使用 for-range 打印所有内容。

正在加载编辑器...
显示提示

当通道关闭并排空时,通道上的“for range”结束。

3 次尝试后可用的解决方案

Quiz#go.m7.l2.e3
准备好

当发送方发送但接收方尚未准备好时,UNBUFFERED 通道会做什么?

Go
ch := make(chan int)
ch <- 1 // ?
答案选项

回顾

  • Channel = 类型化 FIFO 队列,在 goroutine 之间安全。
  • 无缓冲:会合(发送方和接收方同步)。
  • 缓冲:解耦,仅在满/空时阻塞。
  • close(ch):仅限发件人; for range 消耗直到关闭。
  • 方向性:chan<- T(仅发送)、<-chan T(仅接收)。
  • chan struct{} 作为纯同步的信号通道。