返回顶部
首页 > 资讯 > 后端开发 > GO >浅谈golang通道类型
  • 784
分享到

浅谈golang通道类型

golang通道类型golang通道 2023-02-14 12:02:21 784人浏览 薄情痞子
摘要

目录一、什么是通道类型二、通道产生的原因三、声明channel四、创建channel五、channel相关操作1、发送值2、接收值3、关闭通道六、通道类型1、无缓冲通道2、有缓冲通道

一、什么是通道类型

Go 语言中的通道(channel)是一种特殊的类型。通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序。每一个通道都是一个具体类型的导管,也就是声明channel的时候需要为其指定元素类型。

如果说goroutine是Go程序并发的执行体,channel就是它们之间的连接。channel是可以让一个goroutine发送特定值到另一个goroutine的通信机制。

二、通道产生的原因

虽然可以使用共享内存进行数据交换,但是共享内存在不同的goroutine中容易发生竞态问题。为了保证数据交换的正确性,必须使用互斥量对内存进行加,这种做法势必造成性能问题。

Go语言的并发模型是CSP(Communicating Sequential Processes),提倡通过通信共享内存而不是通过共享内存而实现通信。

三、声明channel

语法:

var 变量 chan 元素类型  

例:

var ch1 chan int   // 声明一个传递整型的通道
var ch2 chan bool  // 声明一个传递布尔型的通道
var ch3 chan []int // 声明一个传递int切片的通道   

四、创建channel

语法:

make(chan 元素类型, [缓冲大小])  

注意: 声明的通道后需要使用make函数初始化之后才能使用。channel的缓冲大小是可选的。

例:

ch4 := make(chan int, 3)
ch5 := make(chan bool)
ch6 := make(chan []int)   

五、channel相关操作

1、发送值

将一个值发送到通道中。

例:

ch <- 10 // 把10发送到ch中   

2、接收值

从一个通道中接收值。

例:

x := <- ch // 从ch中接收值并赋值给变量x
<-ch       // 从ch中接收值,忽略结果   

3、关闭通道

例:

close(ch)   

3.1 注意

只有在通知接收方goroutine所有的数据都发送完毕的时候才需要关闭通道。通道是可以被垃圾回收机制回收的,它和关闭文件是不一样的,在结束操作之后关闭文件是必须要做的,但关闭通道不是必须的。

3.2 特点

  • 对一个关闭的通道再发送值就会导致panic。
  • 对一个关闭的通道进行接收会一直获取值直到通道为空。
  • 对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。
  • 关闭一个已经关闭的通道会导致panic。

六、通道类型

1、无缓冲通道

无缓冲的通道只有在有人接收值的时候才能发送值。就像你住的小区没有快递柜和代收点,快递员给你打电话必须要把这个物品送到你的手中,简单来说就是无缓冲的通道必须有接收才能发送。

语法:

ch := make(chan type) 

例:

func recv(c chan int) {
    ret := <-c
    fmt.Println("接收成功", ret)
}
func main() {
    ch := make(chan int)
    go recv(ch) // 启用goroutine从通道接收值
    ch <- 10
    fmt.Println("发送成功")
}  

分析: 无缓冲通道上的发送操作会阻塞,直到另一个goroutine在该通道上执行接收操作,这时值才能发送成功,两个goroutine将继续执行。相反,如果接收操作先执行,接收方的goroutine将阻塞,直到另一个goroutine在该通道上发送一个值。

2、有缓冲通道

只要通道的容量大于零,那么该通道就是有缓冲的通道,通道的容量表示通道中能存放元素的数量。就像你小区的快递柜只有那么个多格子,格子满了就装不下了,就阻塞了,等到别人取走一个快递员就能往里面放一个。

语法:

ch := make(chan type, [cap]) 

例:

func main() {
    ch := make(chan int, 1) // 创建一个容量为1的有缓冲区通道
    ch <- 10
    fmt.Println("发送成功")
}   

七、单向通道

有的时候我们会将通道作为参数在多个任务函数间传递,很多时候我们在不同的任务函数中使用通道都会对其进行限制,比如限制通道在函数中只能发送或只能接收。

语法:

chan<- int  是一个只能发送的通道,可以发送但是不能接收;
<-chan int  是一个只能接收的通道,可以接收但是不能发送。

例:

func counter(out chan<- int) {
    for i := 0; i < 100; i++ {
        out <- i
    }
    close(out)
}

func squarer(out chan<- int, in <-chan int) {
    for i := range in {
        out <- i * i
    }
    close(out)
}
func printer(in <-chan int) {
    for i := range in {
        fmt.Println(i)
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    go counter(ch1)
    go squarer(ch2, ch1)
    printer(ch2)
}

注意: 在函数传参及任何赋值操作中将双向通道转换为单向通道是可以的,但反过来是不可以的。

八、从通道循环取值

例:

// channel 练习
func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)
    // 开启goroutine将0~100的数发送到ch1中
    go func() {
        for i := 0; i < 100; i++ {
            ch1 <- i
        }
        close(ch1)
    }()
    // 开启goroutine从ch1中接收值,并将该值的平方发送到ch2中
    go func() {
        for {
            i, ok := <-ch1 // 通道关闭后再取值ok=false
            if !ok {
                break
            }
            ch2 <- i * i
        }
        close(ch2)
    }()
    // 在主goroutine中从ch2中接收值打印
    for i := range ch2 { // 通道关闭后会退出for range循环
        fmt.Println(i)
    }
}   

分析: 有两种方式在接收值的时候判断通道是否被关闭,我们通常使用的是for range的方式。

到此这篇关于浅谈golang通道类型的文章就介绍到这了,更多相关golang 通道类型内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

您可能感兴趣的文档:

--结束END--

本文标题: 浅谈golang通道类型

本文链接: https://lsjlt.com/news/195998.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 浅谈golang通道类型
    目录一、什么是通道类型二、通道产生的原因三、声明channel四、创建channel五、channel相关操作1、发送值2、接收值3、关闭通道六、通道类型1、无缓冲通道2、有缓冲通道...
    99+
    2023-02-14
    golang 通道类型 golang 通道
  • 浅谈spring aop的五种通知类型
    spring aop通知(advice)分成五类: 前置通知[Before advice]:在连接点前面执行,前置通知不会影响连接点的执行,除非此处抛出异常。 正常返回通知[After returning advice]...
    99+
    2023-05-30
    spring aop 通知
  • 浅谈Python的文件类型
    Python的文件类型主要分为3种:源代码(source file)、字节码(byte-code file)、优化的字节码(optimized file)。这些代码都可以直接运行,不需要编译或者连接。这正是...
    99+
    2022-06-04
    浅谈 文件类型 Python
  • Kotlin空安全空类型浅谈
    目录正文一、判断可空变量是否为null的方式二、涉及到返回可空值的函数使用方法,在返回类型后同时加?三、let操作符四、Evils操作符(: !! as)总结:正文 首先非空变量和可...
    99+
    2024-04-02
  • 浅谈Mybatis+mysql 存储Date类型的坑
    场景: 把一个时间字符串转成Date,存进Mysql。时间天数会比实际时间少1天,也可能是小时少了13-14小时 Mysql的时区是CST(使用语句:show VARIABLES LIKE '%time_zone%'...
    99+
    2022-05-25
    Mybatis mysql 存储Date类型
  • 浅谈MySQL中分区表基本类型
    小编这次要给大家分享的是浅谈MySQL中分区表基本类型,文章内容丰富,感兴趣的小伙伴可以来了解一下,希望大家阅读完这篇文章之后能够有所收获。MySQL分区表概述随着MySQL越来越流行,Mysql里面的保存...
    99+
    2024-04-02
  • 浅谈node.js中间件有哪些类型
    目录概述1、应用级中间件2、内置中间件3、第三方中间件(1)body-parser,将post请求数据解析为对象(2)mysql模块概述 node中间件就是封装在程序中处理http请...
    99+
    2024-04-02
  • 浅谈python数据类型及其操作
    目录一、Number 数字二、String 字符串三、List 列表四、Tuple 元组五、Sets集合六、Dictionary 字典 (非常重要)一、Number 数字 1.内置...
    99+
    2024-04-02
  • 浅谈C++类型转换几种情况
    目录0. 类型转换的原理1. 初始化和赋值时进行的转换2. 以{}方式初始化时进行的转换(C++11新增)3. 表达式中的转换4. 传递参数时的转换5. 强制类型转换6. 使用aut...
    99+
    2024-04-02
  • 浅谈Mybatis传参类型如何确定
    目录I.环境配置1.项目配置2.数据库表II.传参类型确定1.参数类型为整形2.指定jdbcType3.传参类型为String4.TypeHandler实现参数替换强制添加引号5.小...
    99+
    2024-04-02
  • 浅谈Python数据类型之间的转换
    Python数据类型之间的转换 函数 描述 int(x [,base]) 将...
    99+
    2022-06-04
    浅谈 数据类型 Python
  • MySQL数据类型之浅谈字符串(string)
    目录字符类型(CHAR Types)可变字符类型(Varchar Types)二进制类型(BINARY Types)可变二进制类型(VARBINARY Types)二进制大对象类型(BLOB Types)文本类型(Tex...
    99+
    2024-04-02
  • 浅谈怎么给Python添加类型标注
    Python 添加类型标注 Python 如此简洁,书写者在声明变量时甚至无需考虑类型。 但是简洁与复杂间,是存在一个平衡点的。当我们书写较为复杂的项目时,还是希望可以拥有「静态类型...
    99+
    2024-04-02
  • 浅谈JavaScript原型链
    目录instanceof 简介Function instanceof Function instanceof 运算符的定义JavaScript 原型继承机制原型与原型链原型继承Obj...
    99+
    2023-05-17
    JavaScript原型 原型链 JavaScript原型链 JavaScript原型
  • Golang函数并发编程中通道的类型和规则
    通道是 go 语言中用于在并发函数间安全传递数据的通信机制,提供的数据竞争保护避免直接访问共享内存。通道类型包括无缓冲通道(chan t)和缓冲通道(chan t, int)。规则包括发...
    99+
    2024-04-18
    并发 通道 golang
  • 浅谈Golang内存逃逸
    目录1.什么是内存逃逸2.什么是逃逸分析3.小结4.逃逸分析案例1.函数返回局部指针变量2.interface类型逃逸1.interface产生逃逸2.指向栈对象的指针不能在堆中3....
    99+
    2024-04-02
  • 浅谈Golang数据竞态
    目录一个数据竞态的case检查数据竞态解决方案1、WaitGroup等待2、Channel阻塞等待3、Channel通道4、互斥锁典型数据竞态1、循环计数上的竞态2、意外共享变量3、...
    99+
    2023-02-08
    Golang数据竞态
  • 浅谈golang的json.Unmarshal的坑
    最近在golang业务开发时,遇到一个坑。 我们有个服务,会接收通用的interface对象,然后去给用户发消息。因此会涉及到把各个业务方传递过来的字符串,转成interface对象...
    99+
    2023-01-05
    golang json.Unmarshal
  • 浅谈String类型如何转换为time类型存进数据库
    目录String转换为time存进数据库这里就列举一个例子java里面的类型是string类型我用的是java提供的传统的jdbc接口连接数据库String类型的数字转换为时间日期格...
    99+
    2024-04-02
  • Golang通脉之类型定义
    目录1、自定义类型2、类型定义2.1 定义结构体2.2 定义接口2.3 定义其他的新类型2.4 定义函数的类型3、类型别名4、类型定义和类型别名的区别5、非本地类型不能定义方法6、在...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作