首页 > 其他分享 >Golang中的Channel(一)

Golang中的Channel(一)

时间:2023-07-07 15:33:10浏览次数:37  
标签:缓冲 goroutine chan 阻塞 Golang Channel channel

Golang在并发编程上有两大利器,分别是channel和goroutine。Golang中有一句名言:“使用通信来共享内存,而不是通过共享内存来通信”。这句话有两层意思,Go语言确实在sync包中提供了传统的锁机制,但更推荐使用channel来解决并发问题。这里先对Channel做一个基本的介绍,对于其深一层的实现原理,等今后有空了再学习总结一下。

 

u 什么是Channel

从字面上理解,channel的意思是管道。它是一种go协程用以接收或发送消息的安全的消息队列。channel就像两个go协程之间的导管,来实现各种资源的同步。如图示意:

https://user-gold-cdn.xitu.io/2019/12/8/16ee5c45b1dcb0ea?imageslim

Channel 是进程内的通信方式,因此通过 channel 传递对象的过程和调用函数时的参数传递行为比较一致,比如也可以传递指针等。使用channel发送和接收所需的共享资源,可以在 goroutine 之间消除竞争条件。Channel 是类型相关的,也就是说,一个 channel只能传递一种类型的值,这个类型需要在声明 channel 时指定。

 

u Channel的类型以及有无缓冲的channel

channel类型的定义格式如下:

ChannelType = ( "chan" | "chan" "<-" | "<-" "chan" ) ElementType .

它包括三种类型的定义。可选的<-代表channel的方向。如果没有指定方向,那么Channel就是双向的,既可以接收数据,也可以发送数据:

    chan T          // 可以接收和发送类型为 T 的数据

    chan<- float64  // 只可以用来发送 float64 类型的数据

    <-chan int      // 只可以用来接收 int 类型的数据

       

        <-总是优先和最左边的类型结合:

        chan<- chan int    // 等价 chan<- (chan int)

    chan<- <-chan int  // 等价 chan<- (<-chan int)

    <-chan <-chan int  // 等价 <-chan (<-chan int)

    chan (<-chan int)

 

       使用make初始化Channel,并且可以设置容量:

       make(chan int, 100)

容量代表channel容纳的最多的元素的数量,代表Channel的缓存的大小。如果没有设置容量,或者容量设置为0, 说明Channel没有缓存,只有sender和receiver都准备好了后它们的通讯才会发生。如果设置了缓存,就可能不发生阻塞,只有buffer满了后 send才会阻塞,而只有缓存空了后receive才会阻塞。一个nil channel不会通信。这就构成了所谓的Unbuffered Channels和Buffered Channels:

 

²  Unbuffered Channels

指缓冲区大小为0的channel,接收者会阻塞直至接收到消息,发送者会阻塞直至接收者接收到消息,这种机制可

用于两个goroutine进行状态同步。下图可以形象说明两个goroutine如何利用无缓冲的channel来共享

一个值(下图来自互联网):

 

 

²  Buffered Channels

指缓冲区大小不为0的channel,当缓冲区已满时,发送者会阻塞;当缓冲区为空时,接收者会阻塞。

这种类型的通道并不强制要求goroutine 之间必须同时完成发送和接收。这导致有缓冲的通道和无缓冲的通道之间的一

个很大的不同:无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换;有缓冲的通道没有这种

保证。

同样可以以下图来展示:

 

标签:缓冲,goroutine,chan,阻塞,Golang,Channel,channel
From: https://www.cnblogs.com/gongxianjin/p/17535123.html

相关文章

  • Golang的类图
    @目录1.依赖(Dependency)1.1概念1.2代码示例1.3类图示例2.泛化(Generalization)-继承2.1概念2.2代码示例2.3类图3.泛化(Generalization)-实现3.1概念3.2代码示例3.3类图4.关联关系(Association)4.1概念4.2代码示例4.3类图5.聚合关系(Aggregation)5.1概念5.2代码示例5.3......
  • golang 解析yaml文件
    初始化packagemainimport( "github.com/spf13/viper")funcinitConfig(){ viper.SetConfigName("config") viper.AddConfigPath("./") iferr:=viper.ReadInConfig();err!=nil{ fmt.Println("Initsetingerror:",......
  • golang之http请求库go-resty
     github: https://github.com/go-resty/resty go-resty特性#go-resty 有很多特性:发起GET,POST,PUT,DELETE,HEAD,PATCH,OPTIONS,etc.请求简单的链式书写自动解析JSON和XML类型的文档上传文件重试功能客户端测试功能RestyclientCustom RootCertificates andC......
  • 【Netty】「萌新入门」(三)ChannelFuture 与 CloseFuture
    前言本篇博文是《从0到1学习Netty》中入门系列的第三篇博文,主要内容是介绍Netty中ChannelFuture与CloseFuture的使用,解决连接问题与关闭问题,往期系列文章请访问博主的Netty专栏,博文中的所有代码全部收集在博主的GitHub仓库中;连接问题与ChannelFuture在Netty中,所有的......
  • Golang起步篇
    一.安装Go语言开发环境1.Wondows下搭建Go开发环境(1).下载SDK工具包sdk下载地址为:https://go.dev/dl/(2).解压下载的压缩包,放到特定的目录下,我一般放在d:/programs下(路径不能有中文或者特殊符号如空格等)(3).配置环境变量步骤1:先打开环境变量配置的界面步骤2:配置......
  • golang解决go get下载失败解决办法
    原因:所下载的库依赖有官方库,而官方被封禁网导致。方法:设置代理goenv-wGOPROXY=https://goproxy.cnps:go1.11发布后,还发布一个goproxy提供代理服务,goproxy.cn是专门服务于中国的,依赖于七牛云github地址:https://github.com/goproxy......
  • golang汇编学习(寄存器)
    好久没有写博客了,上一篇写的汇编只是简单的调试了一下,这段时间又看了下,做一个简单的汇总。两个代码汇编代码,1_amd64.sTEXT·add(SB),$0-0MOVQa+0(FP),AXMOVQb+8(FP),BXADDQAX,BXMOVQBX,c+16(FP)RET主函数1.gopackagemainfuncadd(a,bint)intfuncmain()......
  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel-......
  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel......
  • Golang实现图片与视频的缩略图生成
    图片与视频的缩略图是一个十分常见的需求,比如即时消息。这里摘取了Golang项目中的相关代码,分享图片与视频相关处理的开发经验。图片缩略图缩略图的尺寸分为两种规则:1)边长模式,生成正方形缩略图;2)宽高模式,又分三种:指定宽高、指定宽(高等比缩放)、指定高(宽等比缩放)。如果原图为png或gif,缩......