侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

go语言中什么是通道(channel)?通道详解

Go  /  管理员 发布于 2年前   808

通信介绍

假设有这样一个变量,这个变量需要实现协程间共享。由于协程之间存在隔离性,这时候我们该如何实现呢?

我们可以通过数据库、Redis等类似的组件去实现协程之间共享内存变量。

通过Redis、数据库等方式实现共享。就会面临一个问题,就是对于该变量的竞争,谁先具有执行优先权,修改该变量之后之后,又该如何处理?

这或许就需要用到锁机制,但使用锁就会降低并发。

因此Golang中解决该场景的问题是通过,通信来实现共享变量,而不是通过共享内存来实现共享变量。


通道作用

用于协程之间同步与通信。


通道定义

通道定义通过chan关键字。

// 方式一
var 变量名 chan 值类型
变量名 = make(chan 值类型, 通道长度)
// 方式二
变量名 := make(chan 值类型, 通道长度)

ps:

通道长度指的是通道容量大小。向通道出入数据的数量不能超过容量大小。


示例代码:

package main

import (
"fmt"
_ "sync"
"time"
)

func Show(ch1 chan int) {
val := <-ch1
fmt.Println("通道的值是:", val)
}

func main() {
ch1 := make(chan int, 10)

for i := 0; i < 10; i++ {
go Show(ch1)
ch1 <- i
}

time.Sleep(time.Second * 10)

close(ch1)

fmt.Println("所有的协程已经结束了,主线程可以结束了。")
}

通道操作

通道有三种操作方式。

1.发送数据。

 通道名称 <- 传递值

2.接收数据。

值,  BooleanVal: =  <- 通道名称

当BooleanVal值为false时,表示通道不存在值,为true时,通道存在值。在用非range方式循环取通道值的情况下,可以通过该返回值判断通道是否存在值,避免一直循环通道。

3.关闭通道。

close(通道名称)


通道原理

通道可以理解为一个队列。一端想队列中写入数据,另外一个端从队列中读取数据。同时也遵循队列先进先出的特点。


注意事项

1.向一个通道写入数据之后,就可以关闭通道。在通道关闭之后,仍然能够向通道中读取数据。

2.向通道中写入数据完毕之后,需要关闭通道,否则会出现如下错误信息。

fatal error: all goroutines are asleep - deadlock!

3.循环读取通道数据,推荐使用for k, v :range {}方式进行读取。避免使用for循环。

   >方式进行读取。避免使用for循环。rang在循环完通道,会自动退出,不会继续循环。

4.对一个关闭的通道再发送值就会导致panic。

5.对一个关闭的通道进行接收会一直获取值直到通道为空。

6.对一个关闭的并且没有值的通道执行接收操作会得到对应类型的零值。

7.关闭一个已经关闭的通道会导致panic。

8.通道存储的数据,可以是任意类型。

   例如,字符串、Boolean、数字、结构体、接口等。

9.通道只能存储单一类型,如果需要存储多类型,推荐定义通道时,使用intearface类型。并且对读取通道值时,部分数据类型需要做断言处理。


  • 上一条:
    go语言中结构体struct转map及功能实现示例代码
    下一条:
    go语言中实现同一个通道数据的读与写功能示例代码
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期文章
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • PHP 8.4 Alpha 1现已发布!(0个评论)
    • Laravel 11.15版本发布 - Eloquent Builder中添加的泛型(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-09
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-12
    • 2021-01
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-08
    • 2024-11
    • 2025-02
    • 2025-04
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客