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区别的更多相关文章

  1. Golang并发编程有缓冲通道和无缓冲通道(channel)

    无缓冲通道 是指在接收前没有能力保存任何值得通道.这种类型的通道要求发送goroutine和接收goroutine同时准备好,才能完成发送和接收操作.如果两个goroutine没有同时准备好,通道会导 ...

  2. golang的缓冲channel和无缓冲channel的区别

    话说golang的channel同步的定义真是让人无力吐槽,码农的用户体验就这么难搞么,超耐磨阿,无缓冲和缓冲居然有这么大区别....靠 转载一段网上的资料 --------------------- ...

  3. 论C语言中二级指针和二维数组之间的区别

    刚开始学习C语言的时候,觉得一个数组可以定义一个一级指针去访问,想当然的就觉得可以定义一个二级指针去访问二维数组.很显然这是错误的. 我们来看看C语言的数组在内存中的存储方式. 实际上C语言中的数组, ...

  4. C语言中整形数组、字符数组、字符串的区别

    一. 第一 整型数组的存放,数组最后是不加'\0'的,字符串会自动加上,因此存放字符的时候数组的大小要比实际字符的多一个 第二 整型数组 每一个单元是4个字节的,字符串是一个一个字符存放的,每个字符占 ...

  5. C语言中指针*p[N], (*P)[N],及**p的区别

    在C语言编程中指针经常困扰着我们,但是若能灵活运用指针的话,将会使得我们编程变得更加轻松与高效.这里讲下*p[N], (*P)[N],及**p的区别,这也是之前经常困扰我的地方. 这三者的定义分别为: ...

  6. C语言中访问结构体成员时用‘.’和‘->’的区别

    举个例子,定义了一个叫Student,别名为stu的结构类型,我们声明了一个结构体变量叫stu1,声明了一个结构体指针为stuP. typedef struct Student { char name ...

  7. C语言中各数据类型(eg.int和float的区别)

  8. go之无缓冲channel(通道)和有缓冲channel(通道)

    channel我们先来看一下通道的解释:channel是Go语言中的一个核心类型,可以把它看成管道.并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度.chann ...

  9. Go语言中的并发编程

    并发是编程里面一个非常重要的概念,Go语言在语言层面天生支持并发,这也是Go语言流行的一个很重要的原因. Go语言中的并发编程 并发与并行 并发:同一时间段内执行多个任务(你在用微信和两个女朋友聊天) ...

随机推荐

  1. 常用的 TCP KeepAlive 参数

    转自:http://dola.xinfan.org/?p=359 我们知道 TCP 协议有检测连接状态的机制,当连接不活跃的时候,连接双方会通过一定的算法检测连接是否正常.这个机制就是 TCP 的 K ...

  2. input type

    input的type有: text 文本输入 password密码输入 file选择文件 radio单选按钮 checkbox复选按钮 submit对应form的action按钮 button 普通按 ...

  3. golang:三次握手四次挥手总结

    TCP的三次握手 所谓三次握手 Three-Way Handshake 是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立.好比两个人在打电话: 当连接被建立或被终止,交换的报 ...

  4. Advanced Archive Password Recovery (ARCHPR) 是一个强大的压缩包密码破解工具,适用于ZIP和RAR档案的高度优化的口令恢复工具。

    RAR压缩文件密码破解工具是一款简单易用的RAR文档和ZIP文档密码破解软件,如果你不小心忘了解压密码或是下载的RAR文件需要密码,那么均可以使用本软件进行暴力破解.不管WinRAR /RAR 的密码 ...

  5. nohup /usr/local/node/bin/node /www/im/chat.js >> /usr/local/node/output.log 2>&1 &

    nohup和&后台运行,进程查看及终止   &后台运行 登出ssh终端,进程会被自动kill掉 但是nohup >>XX.log 2>&1 & 登出终 ...

  6. Win7通过cmd进入d盘的方法

    Win7通过cmd进入d盘的方法 时间:2016-05-13 15:06:03 作者:yunchun 来源:系统之家  手机查看 评论 我们在使用Win7系统过程中,对于经常使用DOS程序的朋友们来说 ...

  7. python3.7[列表] 索引切片

    python3.7[列表] 索引  切片 排序     #### 列表.sort 永久排序   sorted(列表) 临时排序   ### >>> print(sorted(a))[ ...

  8. VMware虚拟机性能优化

    一.ESX及vCenter服务器的优化 检查ESX物理服务器是否在兼容列表中,特别是BIOS的版本是否符合ESX版本的要求 开启ESX物理服务器硬件虚拟化技术VT-X,AMD-V 关闭BIOS中的英特 ...

  9. Ubuntu 18.04安装 Adob Flash player

    1.Ctrl + Alt + T 打开命令终端,启用Canonical Partners Repository存储库 (最新的Flash插件位于Canonical Partners的存储库中,默认情况 ...

  10. make clean 和 make distclean区别-(转自秋水Leo)

    make clean仅仅是清除之前编译的可执行文件及配置文件. 而make distclean要清除所有生成的文件. Makefile 在符合GNU Makefiel惯例的Makefile中,包含了一 ...