管道用于 goroutine 之间的通信,支持缓冲和无缓冲模式。无缓冲管道遵循 fifo 原则,在接收方准备好前阻塞发送方;有缓冲管道则允许一定容量的数据存储,可避免阻塞。
使用 Go 语言中的管道进行缓冲或无缓冲通信
管道是一种轻量级的通信机制,它允许 Go 协程(goroutine)之间交换数据。管道可以是缓冲的或无缓冲的。
无缓冲管道
无缓冲管道是一个先入先出的(FIFO)队列,它只会在数据的接收方准备好接收数据时存储数据。如果发送方尝试向一个已满的管道发送数据,它将阻塞直到管道中有空间。同样,如果接收方尝试从一个空的管道接收数据,它将阻塞直到管道中有数据。
无缓冲管道用于需要实时通信的情况,例如流式处理。
创建无缓冲管道:
var ch = make(chan int) // 创建一个无缓冲管道
登录后复制
使用无缓冲管道:
go func() { for i := 0; i < 10; i++ { ch <- i // 发送数据到管道 } }() for i := 0; i < 10; i++ { <-ch // 从管道接收数据 }
登录后复制
有缓冲管道
有缓冲管道是一个固定大小的队列,它可以存储多个元素。如果发送方尝试向一个已满的管道发送数据,它不会阻塞,而是将数据丢弃。同样,如果接收方尝试从一个空的管道接收数据,它不会阻塞,而是返回一个特殊值。
有缓冲管道用于需要在发送方和接收方之间进行缓冲的情况,例如缓存任务。
创建有缓冲管道:
var ch = make(chan int, 10) // 创建一个容量为 10 的有缓冲管道
登录后复制
使用有缓冲管道:
go func() { for i := 0; i < 20; i++ { ch <- i // 发送数据到管道 } }() for i := 0; i < 20; i++ { if v, ok := <-ch; ok { // 接收数据 } else { // 通道已关闭 } }
登录后复制
实战案例:
以下是使用管道进行缓冲或无缓冲通信的一个实战案例:
产生整数流
func generateInts(ch chan<- int) { for i := 0; ; i++ { ch <- i } }
登录后复制
缓冲筛选器
func bufferedFilter(ch <-chan int, out chan<- int) { for { i := <-ch if i%2 == 0 { out <- i } } }
登录后复制
无缓冲合并器
func unbufferedMerge(ch1, ch2 <-chan int, out chan<- int) { for { select { case i := <-ch1: out <- i case i := <-ch2: out <- i } } }
登录后复制
主函数
func main() { // 生成整数流 ints := make(chan int) go generateInts(ints) // 缓冲筛选器 buf := make(chan int, 10) go bufferedFilter(ints, buf) // 无缓冲合并器 out := make(chan int) go unbufferedMerge(buf, ints, out) // 输出结果 for i := range out { fmt.Println(i) } }
登录后复制
这个案例演示了如何使用管道从整数流中过滤偶数并以无缓冲合并器进行合并。
以上就是如何使用 Go 语言中的管道进行缓冲或无缓冲通信?的详细内容,更多请关注叮当号网其它相关文章!
文章来自互联网,只做分享使用。发布者:周斌,转转请注明出处:https://www.dingdanghao.com/article/498882.html