channel
我们先来看一下通道的解释:
channel是Go语言中的一个核心类型,可以把它看成管道。并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度。
channel是一个数据类型,主要用来解决go程的同步问题以及协程之间数据共享(数据传递)的问题。
goroutine运行在相同的地址空间,因此访问共享内存必须做好同步。goroutine 奉行通过通信来共享内存,而不是共享内存来通信。
引用类型 channel可用于多个 goroutine 通讯。其内部实现了同步,确保并发安全。

定义channel和使用
和map类似,channel也一个对应make创建的底层数据结构的引用。
当我们复制一个channel或用于函数参数传递时,我们只是拷贝了一个channel引用,因此调用者和被调用者将引用同一个channel对象。和其它的引用类型一样,channel的零值也是nil。
定义一个channel时,也需要定义发送到channel的值的类型。channel可以使用内置的make()函数来创建:
我们先来看一段代码

package main
import "fmt"
func main(){
ch:=make(chan int) //这里就是创建了一个channel,这是无缓冲管道注意
go func(){ //创建子go程
for i:=0;i<6;i++{
ch<-i //循环写入管道
fmt.Println("写入",i)
}
}()

for i:=0;i<6;i++{ //主go程
num:=<-ch //循环读出管道
fmt.Println("读出",num)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
我们先看一下运行结果再来看代码:

我们在代码中 先创建了一个匿名函数的子go程,和main的主go程一起争夺cpu,但是我们在里面创建了一个管道,无缓冲管道有一个规则那就是必须读写同时操作才会有效果,如果只进行读或者只进行写那么会被阻塞,被暂时停顿等待另外一方的操作,在这里我们定义了一个容量为0的通道,这就是无缓冲通道,如下图

无缓冲通道就是这样,一次只能传输一个数据
总结一下就是无缓冲特性:
同一时刻,同时有 读、写两端把持 channel。
如果只有读端,没有写端,那么 “读端”阻塞。
如果只有写端,没有读端,那么 “写端”阻塞。
读channel: <- channel
写channel: channel <- 数据

有缓冲channel
如图所示:

. 在第 1 步,右侧的 goroutine 正在从通道接收一个值。
在第 2 步,右侧的这个 goroutine独立完成了接收值的动作,而左侧的 goroutine 正在发送一个新值到通道里。
在第 3 步,左侧的goroutine 还在向通道发送新值,而右侧的 goroutine 正在从通道接收另外一个值。这个步骤里的两个操作既不是同步的,也不会互相阻塞。
最后,在第 4 步,所有的发送和接收都完成,而通道里还有几个值,也有一些空间可以存更多的值。
有缓冲通道就是图中所示,一方可以写入很多数据,不用等对方的操作,而另外一方也可以直接拿出数据,不需要等对方写,但是注意一点(如果写入的一方把channel写满了,那么如果要继续写就要等对方取数据后才能继续写入,这也是一种阻塞,读出数据也是一样,如果里面没有数据则不能取,就要等对方写入),而有缓冲channel定义也比较简单

ch:=make(chan int,10)//chan int 只能写入读入int类型的数据,10代表容量为10.
1
这里用了自动推导类型来声明了一个有缓冲的channel
总结起来就是:
channel 中自带缓冲区。创建时可以指定缓冲区的大小。
w:直到缓冲区被填满后,写端才会阻塞。
r:缓冲区被读空,读端才会阻塞。
len:代表缓冲区中,剩余元素个数,
cap:代表缓冲区的容量。
在这里可以举个小小的例子来解释一下有缓冲channel和无缓冲channel
同步通信: 数据发送端,和数据接收端,必须同时在线。 —— 无缓冲channel
打电话。打电话只有等对方接收才会通,要不然只能阻塞

异步通信:数据发送端,发送完数据,立即返回。数据接收端有可能立即读取,也可能延迟处理。 —— 有缓冲channel 不用等对方接受,只需发送过去就行
发信息。短信。
是不是很形象呢
下一节将讲解一下channel常见的陷阱以及关闭channel

————————————————
版权声明:本文为CSDN博主「sgsgy5」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sgsgy5/article/details/82054902

go之无缓冲channel(通道)和有缓冲channel(通道)的更多相关文章

  1. Halcon学习之三:有关图像通道的函数(R是三通道,B是1通道,G二通道),排列顺序BGR

    黑白摄像机会返回每个像素所对应的能量采用结果,这些结果组成了一幅单通道灰度值图像,而对于RGB彩色摄像机,它将返回每个像素所对应的三个采样结果,也就是一幅三通道图像.下面这些是与图像通道有关的函数: ...

  2. Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'type' for exchange 'me

    在启动RabbitMQ消费端的时候报错:Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol ...

  3. STM32F10x_ADC三通道DMA连续转换(3通道、软件单次触发)

    Ⅰ.概述 上一篇文章讲述的内容是:三通道逐次转换(单次.单通道软件触发),也就是说3条通道要三次软件触发才能完成转换,而且是通过软件读取转换数值. 本文讲述三通道DMA连续转换(3通道.软件单次触发) ...

  4. 使用opencv为没有透明通道的图像加入透明通道

    在图像处理中,我们经常需要处理带透明通道的图片,比如为图片或视频添加水印,为图片或视频添加字幕.贴图等.然而,我们的素材图片未必总是带有透明通道.比如,素材的背景本该透明的地方,却是黑色和白色.有时, ...

  5. 标准I/O缓冲:全缓冲、行缓冲、无缓冲

    说明:我仅仅对网络资源进行了整合,方便学习-.- 基于流的操作终于会调用read或者write函数进行I/O操作.为了使程序的执行效率最高,流对象一般会提供缓冲区,以降低调用系统I/O库函数的次数. ...

  6. EasyNVR摄像机网页Chrome无插件视频播放功能二次开发之通道配置文件上传下载示例代码

    背景需求 熟悉EasyNVR产品的朋友们都知道,产品设计初期根据整个直播流程层级,我们将EasyNVR无插件直播系统划分为:硬件层.能力层.应用层,连接硬件与应用之间的桥梁,同时屏蔽各种厂家硬件的不同 ...

  7. cell下载图片的思路 --无沙盒(内存)缓冲

    // // ViewController.m // 06-表格图片下载 // // Created by jerry on 15/9/7. // Copyright (c) 2015年 jerry. ...

  8. EasyNVR无插件直播服务器软件使用详情功能-通道配置Excel

    背景需求 使用EasyNVR的用户都有知道,由于EasyNVR是将设备与EasyNVR的通道进行绑定的,因此EasyNVR是通过手动的通道配置来进行设备接入的,这样可以做到将设备的和通道对应的接入.但 ...

  9. [bigdata] flume file channel CPU消耗比 memory channel高的原因

    https://www.quora.com/Why-does-flume-take-more-resource-CPU-when-file-channel-is-used-compared-to-wh ...

随机推荐

  1. 【Day1】2.安装运行Python

     视频地址(全部) https://edu.csdn.net/course/detail/26057 课件地址(全部) https://download.csdn.net/download/gentl ...

  2. 2.NumPy简介

    一:NumPy简介 • 官网链接:http://www.numpy.org/ • NumPy教程链接:https://www.yiibai.com/numpy/ • NumPy是Python语言的一个 ...

  3. F - One Occurrence CodeForces - 1000F (线段树+离线处理)

    You are given an array aa consisting of nn integers, and qq queries to it. ii-th query is denoted by ...

  4. java8学习之Lambda表达式深入与流初步

    Lambda表达式深入: 在上一次[http://www.cnblogs.com/webor2006/p/8135873.html]中介绍Lambda表达式的作用时,其中说到这点: 如标红处所说,既然 ...

  5. CSS基础学习-8.CSS盒子模型_标准盒子&&9.CSS怪异盒子

    怪异盒模型 box-sizing:content-box;/*正常盒模型,默认值*/ box-sizing:border-box:/*怪异盒模型,固定了盒子的大小,无论是否添加内边距还是边框,盒子的大 ...

  6. 生产问题之StackOverflowError异常小记

    印象中,这是项目中首次遇到 StackOverflowError,在此做个笔记. (吃饭回来写) …… 吃饭回来后,尝试把代码回退来分析异常产生原因,然而却无法复现这个栈溢出异常……醉了 有缘再见再写 ...

  7. linux 下 svn 重新定位 url

    linux下重新定位SVN URL方法:   如果更换了SVN服务器,就需要重新定位,指向新的SVN URL. 重新定位命令:svn switch --relocate 原svn地址 新svn地址   ...

  8. BZOJ 2157: 旅游 (树链剖分+线段树)

    树链剖分后线段树维护区间最大最小值与和. 支持单点修改与区间取反. 直接写个区间取反标记就行了.线段树板题.(200行6000B+ 1A警告) #include <cstdio> #inc ...

  9. Codeforces Round #449 [ C/A. Nephren gives a riddle ] [ D/B. Ithea Plays With Chtholly ]

    PROBLEM C/A. Nephren gives a riddle 题 http://codeforces.com/contest/896/problem/A codeforces 896a 89 ...

  10. hdu 6065 RXD, tree and sequence

    题 OwO http://acm.hdu.edu.cn/showproblem.php?pid=6065 (2017 Multi-University Training Contest - Team ...