go 缓冲channel示例

一、缓冲channel创建

// 给make函数,传递第2个参数,指定缓冲队列大小
ch := make(chan int, 100)

缓冲channel的使用方式跟无缓冲channel一样,区别就是往channel写输入数据的时候,如果缓存队列还没满,是不会阻塞写操作,例如:上面创建了的channel缓冲队列大小是100,如果写入到channel中,还未被取走的数据大于100,就会阻塞写操作。

二、缓冲channel应用示例

1.示例1

package main

import (
	"fmt"
)

// 定义计算斐波拉契数列的函数,通过channel参数c返回每一步的计算结果
func fibonacci(n int, c chan int) {
	x, y := 0, 1
	for i := 0; i < n; i++ {
		// 返回当前计算结果
		c <- x
		x, y = y, x+y
	}

	// 通过close关闭channel
	close(c)
}

func main() {
	// 定义int类型的channel,缓冲队列大小是10
	c := make(chan int, 10)

	// 创建一个协程,开始计算数列
	go fibonacci(10, c)

	// 通过range关键词,循环遍历channel变量c,从c中读取数据
	// 如果channel没有数据,就阻塞循环,直到channel中有数据
	// 如果channel关闭,则退出循环
	for i := range c {
		fmt.Println(i)
	}
}

运行结果如下:

0
1
1
2
3
5
8
13
21
34

2.示例2

package main

import (
	"fmt"
	"time"
)

func BufChannel() {
	//创建一个有缓存的channel
	ch := make(chan int, 3) //容量是3

	//len(ch)缓冲区剩余数据个数, cap(ch)缓冲区大小
	fmt.Printf("缓冲区剩余数据个数:%d, 缓冲区大小:%d\n", len(ch), cap(ch))

	//新建协程
	go func() {
		for i := 1; i <= 10; i++ { //这里数据量大于管道容量,会出阻塞
			fmt.Printf("子协程[%d]开始写入: 缓冲区剩余数据个数:%d, 缓冲区大小:%d\n", i, len(ch), cap(ch))
			ch <- i //往chan写内容,如果主协程没读的话,写满3个就会阻塞在此
		}
	}()

	//延时
	fmt.Printf("我要去睡5秒\n")
	time.Sleep(5 * time.Second)
	fmt.Printf("睡醒了\n")

	for i := 1; i <= 10; i++ { //这里数据量大于管道容量,会出阻塞
		fmt.Printf("子协程[%d]准备读出: 缓冲区剩余数据个数:%d, 缓冲区大小:%d\n", i, len(ch), cap(ch))
		num := <-ch //读管道中内容,没有内容前,阻塞
		fmt.Printf("子协程[%d]已读,读出结果为[%d]: 缓冲区剩余数据个数:%d, 缓冲区大小:%d\n", i, num, len(ch), cap(ch))
	}

}

func main() {
	// 有缓冲通道
	BufChannel()
}

运行结果

缓冲区剩余数据个数:0, 缓冲区大小:3
我要去睡5秒
子协程[1]开始写入: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[2]开始写入: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[3]开始写入: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[4]开始写入: 缓冲区剩余数据个数:3, 缓冲区大小:3
睡醒了
子协程[1]准备读出: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[1]已读,读出结果为[1]: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[2]准备读出: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[2]已读,读出结果为[2]: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[3]准备读出: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[3]已读,读出结果为[3]: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[4]准备读出: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[4]已读,读出结果为[4]: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[5]准备读出: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[5]开始写入: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[6]开始写入: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[7]开始写入: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[8]开始写入: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[9]开始写入: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[5]已读,读出结果为[5]: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[6]准备读出: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[6]已读,读出结果为[6]: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[7]准备读出: 缓冲区剩余数据个数:3, 缓冲区大小:3
子协程[7]已读,读出结果为[7]: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[8]准备读出: 缓冲区剩余数据个数:2, 缓冲区大小:3
子协程[8]已读,读出结果为[8]: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[9]准备读出: 缓冲区剩余数据个数:1, 缓冲区大小:3
子协程[9]已读,读出结果为[9]: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[10]准备读出: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[10]开始写入: 缓冲区剩余数据个数:0, 缓冲区大小:3
子协程[10]已读,读出结果为[10]: 缓冲区剩余数据个数:0, 缓冲区大小:3
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值