Go 并发:带缓冲的通道

在上一篇文章 《Go 并发:Channel 通道》中,我们讨论了通道的一些基本特性,需要指出的是,之前讨论的通道都是不带缓冲的通道,也就是说从通道接收数据和往通道发送数据都会阻塞,直到有其他 goroutine 往通道发送数据或从通道接收数据。

在这篇文章中,我们继续讨论带缓冲的通道的使用。

带缓冲的通道

可以创建带缓冲的通道。往通道发送数据时,只有当缓冲满时才会阻塞。同理,从通道接收数据时,只有当缓冲为空时才会阻塞。

可以使用 make 函数来创建带缓冲的通道:

ch := make(chan type, capacity)  

其中,capacity 大于 0 时表示通道带缓冲。capacity 默认为 0 ,所以如果省略 capacity 参数则创建不带缓冲的通道。

例子一

package main

import "fmt"

func main() {
   
   
	ch := make(chan string, 2)
	ch <- "lee"
	ch <- "leo"
	fmt.Println(<-ch)
	fmt.Println(<-ch)
}

在上面的程序中,ch := make(chan string, 2) 创建了一个带缓冲的字符串类型通道,缓冲大小为 2,因此,可以连续往该通道发送 2 个字符串数据也不会阻塞。
接下来,往通道发送 2 个字符串,然后从通道读取这两个字符串,并打印出来:

lee
leo

例子二

接着我们来实现一个更复杂点的例子。

package main

import (
	"fmt"
	"time"
)

func write(ch chan int) {
   
   
	for i := 0; i < 5; i++ {
   
   
		ch <- i
		fmt.Println("wrote ", i, "to ch")
	}
	close(ch)
}

func main() {
   
   
	ch := make(chan int, 2)
	go write(ch)
	time.Sleep(2 * time.Second)
	for v := range ch {
   
   
		fmt.Println("read value", v, "from ch")
		time.Sleep(2 * time.Second)
	}
}

在上面的程序中,创建了一个带缓冲的整形通道,缓冲大小为 2 。然后在 main goroutine 中启动了 write goroutine。在 write goroutine 中,循环往通道发送数字 0 - 4。由于通道缓冲大小为 2,故发送数字 0 和 1 后,write goroutine 将阻塞。write goroutine 阻塞前打印:

wrote  0 to ch
wrote  1 to ch

write goroutine 打印上面两行输出后,将会阻塞。main goroutine 在睡眠 2 秒后,从通道 ch 接收数字 0。这时,write goroutine 可以继续往通道发送数字 2:

read value 0 from ch
wrote  2 to ch

接下来,write goroutine 将剩余数字发送,main goroutine 将剩余数字打印出来:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值