Go语言中的有缓冲channel和无缓冲channel区别
Go语言中的有缓冲channel和无缓冲channel区别
结论
ch1:=make(chan int)// 无缓冲
ch2:=make(chan int,1)// 有缓冲
无缓冲: 当向ch1中存值后需要其他协程取值,否则一直阻塞
有缓冲: 不会阻塞,因为缓冲大小是1,只有当放第二个值的时候,第一个还没被人拿走,才会阻塞。
测试程序
测试1,声明无缓冲channel
func Test_1(t *testing.T) {
// 无缓冲
ch := make(chan int)
// fatal error: all goroutines are asleep - deadlock! 协程阻塞,需要另一个协程取走channel中的值
ch <- 1
}
运行结果:
=== RUN Test_1
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
testing.(*T).Run(0xc0000c0100, 0x55bb8e, 0x6, 0x566b20, 0x47e55d)
D:/Go/src/testing/testing.go:961 +0x37e
testing.runTests.func1(0xc0000c0000)
D:/Go/src/testing/testing.go:1202 +0x7f
testing.tRunner(0xc0000c0000, 0xc00008fdc0)
D:/Go/src/testing/testing.go:909 +0xd0
testing.runTests(0xc000060460, 0x654300, 0x4, 0x4, 0x0)
D:/Go/src/testing/testing.go:1200 +0x2ae
testing.(*M).Run(0xc0000b6000, 0x0)
D:/Go/src/testing/testing.go:1117 +0x17d
main.main()
_testmain.go:50 +0x13c
goroutine 19 [chan send]:
test/review.Test_1(0xc0000c0100)
E:/Go/src/test/review/main_test.go:64 +0x57
testing.tRunner(0xc0000c0100, 0x566b20)
D:/Go/src/testing/testing.go:909 +0xd0
created by testing.(*T).Run
D:/Go/src/testing/testing.go:960 +0x357
Process finished with exit code 1
测试2,开启协程取值
func Test_2(t *testing.T) {
// 无缓冲
ch := make(chan int)
go func() {
// 睡眠1秒,等待主协程在channel写入值
time.Sleep(time.Second * 1)
fmt.Println("开始取值。。。")
<-ch
}()
fmt.Println("开始存值。。。")
ch <- 1
time.Sleep(time.Second*5)
fmt.Println("结束。。。")
}
运行结果:
=== RUN Test_2
开始存值。。。
开始取值。。。
结束。。。
--- PASS: Test_2 (6.00s)
PASS
Process finished with exit code 0
测试3,声明有缓冲channel
func Test_3(t *testing.T) {
// 有缓冲
ch1 := make(chan int, 1)
// 缓冲大小为1 即是当channel中有一个值时不会被阻塞,当再塞入一个时前一个没被其他协程取走才会阻塞
ch1 <- 2
// 此时主协程也可取出值
fmt.Println(<-ch1)
}
运行结果:
=== RUN Test_3
2
--- PASS: Test_3 (0.00s)
PASS
Process finished with exit code 0
测试4,存入超过缓冲数量的值
func Test_4(t *testing.T) {
// 有缓冲
ch1 := make(chan int, 1)
// 缓冲大小为1 即是当channel中有一个值时不会被阻塞,当再塞入一个时前一个没被其他携程取走才会阻塞
ch1 <- 1
// fatal error: all goroutines are asleep - deadlock!
ch1 <- 2
}
测试结果:
=== RUN Test_4
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
testing.(*T).Run(0xc0000a8100, 0x55bba0, 0x6, 0x566b40, 0x47e501)
D:/Go/src/testing/testing.go:961 +0x37e
testing.runTests.func1(0xc0000a8000)
D:/Go/src/testing/testing.go:1202 +0x7f
testing.tRunner(0xc0000a8000, 0xc000081dc0)
D:/Go/src/testing/testing.go:909 +0xd0
testing.runTests(0xc0000044c0, 0x654300, 0x4, 0x4, 0x0)
D:/Go/src/testing/testing.go:1200 +0x2ae
testing.(*M).Run(0xc00009e000, 0x0)
D:/Go/src/testing/testing.go:1117 +0x17d
main.main()
_testmain.go:50 +0x13c
goroutine 6 [chan send]:
test/review.Test_4(0xc0000a8100)
E:/Go/src/test/review/main_test.go:97 +0x76
testing.tRunner(0xc0000a8100, 0x566b40)
D:/Go/src/testing/testing.go:909 +0xd0
created by testing.(*T).Run
D:/Go/src/testing/testing.go:960 +0x357
Process finished with exit code 1
Go语言中的有缓冲channel和无缓冲channel区别的更多相关文章
- Golang并发编程有缓冲通道和无缓冲通道(channel)
无缓冲通道 是指在接收前没有能力保存任何值得通道.这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作.如果两个goroutine没有同时准备好,通道会导 ...
- golang的缓冲channel和无缓冲channel的区别
话说golang的channel同步的定义真是让人无力吐槽,码农的用户体验就这么难搞么,超耐磨阿,无缓冲和缓冲居然有这么大区别....靠 转载一段网上的资料 --------------------- ...
- 论C语言中二级指针和二维数组之间的区别
刚开始学习C语言的时候,觉得一个数组可以定义一个一级指针去访问,想当然的就觉得可以定义一个二级指针去访问二维数组.很显然这是错误的. 我们来看看C语言的数组在内存中的存储方式. 实际上C语言中的数组, ...
- C语言中整形数组、字符数组、字符串的区别
一. 第一 整型数组的存放,数组最后是不加'\0'的,字符串会自动加上,因此存放字符的时候数组的大小要比实际字符的多一个 第二 整型数组 每一个单元是4个字节的,字符串是一个一个字符存放的,每个字符占 ...
- C语言中指针*p[N], (*P)[N],及**p的区别
在C语言编程中指针经常困扰着我们,但是若能灵活运用指针的话,将会使得我们编程变得更加轻松与高效.这里讲下*p[N], (*P)[N],及**p的区别,这也是之前经常困扰我的地方. 这三者的定义分别为: ...
- C语言中访问结构体成员时用‘.’和‘->’的区别
举个例子,定义了一个叫Student,别名为stu的结构类型,我们声明了一个结构体变量叫stu1,声明了一个结构体指针为stuP. typedef struct Student { char name ...
- C语言中各数据类型(eg.int和float的区别)
- go之无缓冲channel(通道)和有缓冲channel(通道)
channel我们先来看一下通道的解释:channel是Go语言中的一个核心类型,可以把它看成管道.并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度.chann ...
- Go语言中的并发编程
并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因. Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天) ...
随机推荐
- [DB] MapReduce 例题
词频统计(word count) 一篇文章用哈希表统计即可 对互联网所有网页的词频进行统计(Google搜索引擎的需求),无法将所有网页读入内存 map:将单词提取出来,对每个单词输入一个<wo ...
- netperf对比
netperf -H 10.1.60.141 -t TCP_STREAM -l 60 -p 10082 netperf -H 10.1.60.141 -t UDP_STREAM -l 60 -p ...
- 运维实战案例之“Too many open files”错误与解决方法
运维实战案例之"Too many open files"错误与解决方法 技术小甜 2017-11-16 15:02:00 浏览869 服务器 shell tomcat 脚本 o ...
- Linux 根目录所在分区被脏数据占满
背景: 公司在做一个项目,大概功能就是一个通行闸机的人脸识别系统,要经过门禁的人注册了之后,系统就会存储一张原始的图片在服务器的数据文件夹里面,包括了永久的存储和一些访客注册临时存储.一天周五的时 ...
- pgrep cron
# pgrep cron947[root@localhost cron]# pgrep --help Usage: pgrep [options] <pattern> Options: - ...
- 使用Prometheus Operator 监控Kubernetes(15)
一.Prometheus概述: Prometheus是一个开源系统监测和警报工具箱. Prometheus Operator 是 CoreOS 开发的基于 Prometheus 的 Kubernete ...
- inux操作系统测试工具
inux操作系统测试工具 转载minions_222 最后发布于2017-08-02 11:42:13 阅读数 1481 收藏 展开 转自:http://blog.csdn.net/crisscha ...
- python基础之pip、.pyc、三元运算、进制、一切皆对象、可变与不可变类型
一.pip(下载工具==yum) 1.重点(必须掌握的) 列出已安装的包 pip list 安装要安装的包 pip install xxx 安装特定版本 pip install django==1.1 ...
- 『动善时』JMeter基础 — 24、JMeter中使用“用户参数”实现参数化
目录 1.用户参数组件介绍 2.用户参数界面介绍 3.使用"用户参数"组件实现参数化 (1)测试计划内包含的元件 (2)线程组元件内容 (3)HTTP请求组件内容 (4)用户参数组 ...
- Git 分支基本命令
1. 查看当前分支 (git branch) 2. 创建分支 (git branch 分支名) 3.切换分支(git checkout 分支名) 4.分支上的常规操作 5.分支的合并 (git che ...