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类型。并且对读取通道值时,部分数据类型需要做断言处理。
122 在
学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..123 在
Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..原梓番博客 在
在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..博主 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..1111 在
佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
Copyright·© 2019 侯体宗版权所有·
粤ICP备20027696号