Channel 是 goroutines 之间通信的类型化管道——一个 goroutine 发送值,另一个接收它们。Channel 是 Go goroutines 安全传递数据和同步的方式,体现了"通过通信共享内存"的格言。
创建和使用 channels
go
ch := ( )
{
ch <-
}()
value := <-ch
fmt.Println(value)
<- 操作符既发送(ch <- v)也接收(v := <-ch)。
// UNBUFFERED — send blocks until a receiver is ready (synchronization point)
ch := make(chan int)
// sending blocks until another goroutine receives → they "rendezvous"
// BUFFERED — holds up to N values; send blocks only when the buffer is FULL
buf := make(chan int, 3)
buf <- 1; buf <- 2; buf <- 3 // these don't block (buffer has room)
buf <- 4 // blocks now — buffer is full
Unbuffered channels 进行同步:发送等待接收(反之亦然),使其成为一种协调工具。Buffered channels 将发送者和接收者解耦至缓冲区大小。
ch := make(chan int)
go func() {
for i := 0; i < 3; i++ { ch <- i }
close(ch) // signal "no more values" (only the SENDER closes)
}()
for v := range ch { // receives until the channel is CLOSED
fmt.Println(v)
}
// the comma-ok form detects a closed channel
v, ok := <-ch // ok = false if the channel is closed and drained
关闭 channel 表示完成;在 channel 上 range 会接收直到它被关闭。只有发送者应该关闭 channel。
// ❌ deadlock — sending on an unbuffered channel with no receiver
ch := make(chan int)
ch <- 1 // 💥 fatal error: all goroutines asleep - deadlock!
// ❌ panic — operations on/after close
close(ch); close(ch) // 💥 panic: close of closed channel
close(ch); ch <- 1 // 💥 panic: send on closed channel
v := <-closedCh // ✅ OK — receiving from a closed channel returns the zero value
死锁(所有人都被阻塞)和关闭相关的 panic 是常见的 channel bugs。
func producer(out chan<- int) { out <- 1 } // send-only
func consumer(in <-chan int) { <-in } // receive-only
Channels 是 Go 并发模型的核心,也是 goroutines 进行通信和同步的习惯用法——实现了核心哲学"不要通过共享内存来通信;通过通信来共享内存"。它们允许你在并发 goroutines 之间安全地传递数据,无需显式锁,构建管道,分配工作,以及信号完成。
理解发送/接收操作、至关重要的 unbuffered(同步)vs buffered(解耦) 区别、关闭语义(发送者关闭;range/comma-ok 检测它)以及常见的陷阱(死锁来自阻塞的发送/接收,panic 来自关闭两次或在已关闭 channel 上发送)对于编写正确的并发 Go 代码是必不可少的。
Channels(与 goroutines 一起)是 Go 的标志,也是该语言中最重要和最常被测试的概念之一。
一个包含详细解答的 IT 面试题库——从初级到高级。
捐赠