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. linux-TCP多线程的并发服务器- 以言责人甚易,以义持己实难!!!

    1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <ti ...

  2. opencv——形态学深究(分析和应用)

    摘要: 形态学一般指生物学中研究动物和植物结构的一个分支.用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具. 基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对 ...

  3. 白日梦的MySQL专题(第33篇):各种登陆MySQL的骚操作

    阅读原文 系列文章公众号首发,点击阅读原文 前置知识 我们想登陆到mysql中前提是肯定需要一个用户名和密码:比如 mysql -uroot -proot 在mysql中用户的信息会存放在 mysql ...

  4. [Python] Python工匠(Github)

    1.善用变量来改变代码质量 变量命名 变量要有描述性,不能太宽泛 BAD:day, host, cards, temp GOOD:day_of_week, hosts_to_reboot, expir ...

  5. Rust 多态

    Rust 多态 分发 多态的上下文中的方法解析过程被称为分发,调用该方法称为分发化,在支持多态的主流语言中,分发可以通过以下任意一种方式进行. 静态分发 当在编译期决定要调用的方法时,它被称为静态分发 ...

  6. Mysql_二进制方式安装详解

    mysql 安装 1.安装方式 1.二进制安装 2.源码包安装 3.rpm包安装 1.二进制安装 1)上传或者下载包 [root@db01 ~]# rz #或者 [root@web01 ~]# wge ...

  7. dd命令详解-(转自dkcndk)

    Linux-dd命令详解 dd 是 Linux/UNIX 下的一个非常有用的命令,作用是用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换.名称: dd 使用权限: 所有使用者dd 这个指令在 ...

  8. Python将PDF转为TXT

    PDFMiner----python的PDF解析器和分析器 1.官方文档:http://www.unixuser.org/~euske/python/pdfminer/index.html 2.特征 ...

  9. harbor搭建及使用

    harbor搭建及使用   1 系统及软件版本 1.1 系统版本 # uname -a Linux localhost.localdomain 3.10.0-862.el7.x86_64 #1 SMP ...

  10. GO语言练习---对切片进行排序

    对整型切片进行选择排序 package main import "fmt" /*对切片排序*/ func SortSlice(slice []int) { for i := 0; ...