Go 的 chan 底层数据结构和主要使用场景 ?
在Go语言中,chan
(通道)是一种特殊类型,它提供了一种在不同Goroutine之间进行通信的机制。通道在底层是一个阻塞的FIFO队列(先进先出),它可以存储一定数量的值。
底层数据结构:
在Go语言的实现中,chan
是由一个hchan
结构体表示的,这个结构体包含了一些字段,比如:要发送的数据队列、接收数据的Goroutine队列、缓冲区大小等。当你向一个chan
发送数据时,如果这个chan
没有空闲的缓冲区,并且也没有等待接收数据的Goroutine,那么发送Goroutine会被阻塞,直到有Goroutine从这个chan
接收数据。同样的,当你从一个chan
接收数据时,如果这个chan
没有待接收的数据,并且也没有等待发送数据的Goroutine,那么接收Goroutine会被阻塞,直到有Goroutine向这个chan
发送数据。
主要使用场景:
chan
是Go语言并发编程中的重要工具,它的主要应用场景包括:
- Goroutine之间的同步:你可以通过无缓冲的
chan
来同步两个Goroutine,例如等待一个Goroutine完成任务。
done := make(chan bool)
go func() {
fmt.Println("Doing some work...")
// signal that the work is done
done <- true
}()
// wait for the work to be done
<-done
- Goroutine之间的数据传递:你可以用有缓冲的
chan
来在不同Goroutine之间传递数据,实现生产者-消费者模型。
messages := make(chan string, 10)
go func() {
messages <- "hello"
}()
msg := <-messages
fmt.Println(msg) // Output: hello
- 实现并发模式:比如你可以使用
chan
来实现“多路复用”(Multiplexing)和“分发”(Fan-out)、“合并”(Fan-in)等并发模式。