<p>Go语言中channel基于CSP模型实现goroutine间通信,通过发送ch <- value和接收<-ch操作传递数据。无缓冲channel需收发双方同步,有缓冲channel可缓存固定数量数据,缓解阻塞。select语句支持多路复用,实现对多个channel的监听,配合time.After可处理超时。close由发送方调用,关闭后仍可接收数据,for-range循环能自动检测关闭状态,避免panic,提升并发安全性。</p>

Go语言中的channel是实现goroutine之间通信的核心机制。它基于CSP(Communicating Sequential Processes)模型设计,通过显式的值传递来共享数据,而不是依赖共享内存加锁的方式。这种设计让并发编程更安全、直观。
Channel的基本操作
channel支持两种基本操作:发送和接收。使用ch <- value向channel发送数据,用<- ch从channel接收数据。如果channel是带缓冲的,发送操作在缓冲未满时立即返回;若无缓冲或缓冲已满,则发送方会阻塞直到另一方执行接收。
接收操作同样可能阻塞,直到有数据可读。也可以使用双值赋值语法v, ok := <-ch判断channel是否已关闭。
无缓冲与有缓冲channel的区别
无缓冲channel要求发送和接收双方必须同时就绪,否则都会阻塞。这实现了严格的同步通信,常用于事件通知或任务分发。
立即学习“go语言免费学习笔记(深入)”;
- 定义方式:make(chan int) 创建无缓冲channel
- 有缓冲channel则像一个异步队列:make(chan int, 5) 可缓存5个元素
- 当缓冲区未满时,发送不阻塞;未空时,接收不阻塞
Select机制实现多路复用
当需要处理多个channel时,select语句非常有用。它类似于IO多路复用,能监听多个channel的操作状态。
每个case对应一个channel操作,哪个准备好了就执行哪个。如果没有就绪的case且有default分支,则执行default,避免阻塞。
常见模式包括超时控制:
select { case data := <-ch: fmt.Println("收到:", data) case <-time.After(2 * time.Second): fmt.Println("超时") }
关闭channel与遍历
使用close(ch)可以关闭channel,表示不再有数据发送。已关闭的channel不能再发送数据,但可以继续接收,直到所有缓存数据被取完。
for-range循环可自动检测channel关闭:
for v := range ch { fmt.Println(v) }
注意:只有发送方应该调用close(),接收方关闭可能导致程序panic。
基本上就这些。channel的设计让Go的并发模型简洁而强大,合理使用能有效避免竞态条件。
golang go go语言 并发编程 区别 for select int 循环 Go语言 值传递 并发 channel 事件 default 异步


