代码示例
package main
import (
"fmt"
)
// 生产者函数,向通道发送数据
func producer(ch chan int) {
for i := 0; i < 5; i++ {
ch <- i
fmt.Printf("Produced: %d\n", i)
}
close(ch)
}
// 消费者函数,从通道接收数据
func consumer(ch chan int) {
for val := range ch {
fmt.Printf("Consumed: %d\n", val)
}
}
使用示例
func main() {
ch := make(chan int)
go producer(ch)
go consumer(ch)
// 防止主函数退出
select {}
}
无缓冲通道保证数据同步和通信的原理
- 同步:无缓冲通道在发送和接收操作时是阻塞的。当生产者向无缓冲通道发送数据时,如果此时没有消费者在接收数据,生产者会阻塞在
ch <- i
这一行代码处,直到有消费者准备好接收数据。同样,当消费者从无缓冲通道接收数据时,如果此时没有生产者发送数据,消费者会阻塞在 val := <- ch
这一行代码处,直到有生产者发送数据。这种阻塞特性确保了生产者和消费者之间的同步,即数据发送和接收是一一对应的,不会出现数据丢失或竞争条件。
- 通信:无缓冲通道作为生产者和消费者之间的数据桥梁,使得数据能够从生产者传递到消费者。生产者通过
ch <-
语句将数据发送到通道,消费者通过 <- ch
语句从通道接收数据。当生产者发送数据并且消费者接收数据时,数据在两者之间完成了传递,实现了通信功能。另外,通过 close(ch)
关闭通道可以通知消费者没有更多数据,消费者通过 for val := range ch
这种方式可以优雅地处理通道关闭,保证在没有数据时退出循环。