Golang入门到项目实战 | golang并发变成之通道channel Go提供了一种称为通道的机制 , 用于在goroutine之间共享数据 。当您作为goroutine执行并发活动时,需要在goroutine之间共享资源或数据,通道充当goroutine之间的管道(管道)并提供一种机制来保证同步交换 。
根据数据交换的行为,有两种类型的通道:无缓冲通道和缓冲通道 。无缓冲通道用于执行goroutine之间的同步通信,而缓冲通道用于执行异步通信 。无缓冲通道保证在发送和接收发生的瞬间两个goroutine之间的交换 。缓冲通道没有这样的保证 。
通道由make函数创建,该函数指定chan关键字和通道的元素类型 。
这是创建无缓冲和缓冲通道的代码块:
语法
使用内置函数make创建无缓冲和缓冲通道 。make的第一个参数需要关键字chan , 然后是通道允许交换的数据类型 。
这是将值发送到通道的代码块需要使用-运算符:
语法
一个包含5个值的缓冲区的字符串类型的goroutine1通道 。然后我们通过通道发送字符串“Australia” 。
这是从通道接收值的代码块:
语法
- 运算符附加到通道变量(goroutine1)的左侧 , 以接收来自通道的值 。
在无缓冲通道中,在接收到任何值之前没有能力保存它 。在这种类型的通道中,发送和接收goroutine在任何发送或接收操作完成之前的同一时刻都准备就绪 。如果两个goroutine没有在同一时刻准备好 , 则通道会让执行其各自发送或接收操作的goroutine首先等待 。同步是通道上发送和接收之间交互的基础 。没有另一个就不可能发生 。
在缓冲通道中 , 有能力在接收到一个或多个值之前保存它们 。在这种类型的通道中,不要强制goroutine在同一时刻准备好执行发送和接收 。当发送和接收阻塞时也有不同的条件 。只有当通道中没有要接收的值时,接收才会阻塞 。仅当没有可用缓冲区来放置正在发送的值时,发送才会阻塞 。
实例
运行结果
golang - channel通过var声明或者make函数创建go语言缓冲通道怎么设置的channel变量是一个存储在函数栈帧上的指针go语言缓冲通道怎么设置,占用8个字节go语言缓冲通道怎么设置,指向堆上的hchan结构体
源码包中src/runtime/chan.go定义了hchan的数据结构如下go语言缓冲通道怎么设置:
hchan结构体的主要组成部分有四个:
用来保存goroutine之间传递数据的循环数组:buf
用来记录此循环数组当前发送或接收数据的下标值:sendx和recvx
用于保存向该chan发送和从该chan接收数据被阻塞的goroutine队列: sendq 和 recvq
保证channel写入和读取数据时线程安全的锁:lock
环形数组作为channel 的缓冲区 数组的长度就是定义channnel 时channel 的缓冲大小
在hchan 中包括了读/写 等待队列,waitq是一个双向队列 , 包括了一个头结点和尾节点 。每个节点是一个sudog结构体变量
【go语言缓冲通道怎么设置 go语言channel】 channel有2种类型:无缓冲、有缓冲 , 在创建时 make(chan type cap)通过cap 设定缓冲大小
channel有3种模式:写操作模式(单向通道)、读操作模式(单向通道)、读写操作模式(双向通道)
channel有3种状态:未初始化、正常、关闭
如下几种状态会引发panic
channel 是线程安全的 , channel的底层实现中,hchan结构体中采用Mutex锁来保证数据读写安全 。在对循环数组buf中的数据进行入队和出队操作时,必须先获取互斥锁,才能操作channel数据
每天一个知识点:Go 语言当中 Channel(通道)有什么特点 , 需要注意什么?使用简单的 make 调用创建的通道叫做无缓冲通道,但 make 还可以接受第二个可选参数,一个表示通道容量的整数 。如果容量是 0,make 创建一个无缓冲通道 。
无缓冲通道上的发送操作将被阻塞,直到另一个 goroutine 在对应的通道上执行接受操作,这时值传送完成,两个 goroutine 都可以继续执行 。相反,如果接受操作先执行,接收方 goroutine 将阻塞 , 直到另一个 goroutine 在同一个通道上发送一个值 。使用无缓冲通道进行的通信导致发送和接受操作 goroutine 同步化 。因此,无缓冲通道也称为同步通道 。当一个值在无缓冲通道上传递时,接受值后发送方 goroutine 才能被唤醒 。
缓冲通道上的发送操作在队列的尾部插入一个元素,接收操作从队列的头部移除一个元素 。如果通道满了,发送操作会阻塞所在的 goroutine 直到另一个 goroutine 对它进行接收操作来留出可用的空间 。反过来,如果通道是空的,执行接收操作的 goroutine 阻塞,直到另一个 goroutine 在通道上发送数据 。
如果给一个 nil 的 channel 发送数据 , 会造成永远阻塞 。
如果从一个 nil 的 channel 中接收数据,也会造成永久阻塞 。给一个已经关闭的 channel 发送数据 , 会引起 panic 。
从一个已经关闭的 channel 接收数据,如果缓冲区中为空,则返回一个 零 值 。
go语言无缓冲的channel无缓冲go语言缓冲通道怎么设置的通道(unbuffered channel)是指在接收前没有能力保存任何值的通道 。
这种类型的通道要求发送goroutine和接收goroutine同时准备好go语言缓冲通道怎么设置,才能完成发送和接收操作 。否则,通道会导致先执行发送或接收操作的 goroutine 阻塞等待 。
这种对通道进行发送和接收的交互行为本身就是同步的 。其中任意一个操作都无法离开另一个操作单独存在 。
阻塞:由于某种原因数据没有到达,当前协程(线程)持续处于等待状态 , 直到条件满足,才接触阻塞 。
同步:在两个或多个协程(线程)间 , 保持数据内容一致性的机制 。
下图展示两个 goroutine 如何利用无缓冲的通道来共享一个值:
在第 1 步,两个 goroutine 都到达通道,但哪个都没有开始执行发送或者接收 。
在第 2 步,左侧的 goroutine 将它的手伸进go语言缓冲通道怎么设置了通道 , 这模拟了向通道发送数据的行为 。这时,这个 goroutine 会在通道中被锁住 , 直到交换完成 。
在第 3 步,右侧的 goroutine 将它的手放入通道,这模拟了从通道里接收数据 。这个 goroutine 一样也会在通道中被锁?。?直到交换完成 。
在第 4 步和第 5 步,进行交换,并最终 , 在第 6 步,两个 goroutine 都将它们的手从通道里拿出来,这模拟了被锁住的 goroutine 得到释放 。两个 goroutine 现在都可以去做别的事情了 。
如果没有指定缓冲区容量,那么该通道就是同步的,因此会阻塞到发送者准备好发送和接收者准备好接收 。
无缓冲channel: —— 同步通信
关于go语言缓冲通道怎么设置和go语言channel的介绍到此就结束了 , 不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站 。
推荐阅读
- 完美国际私服服务器那个好,完美国际服务器列表
- 皮草工厂直播优选什么意思,优品皮草
- 添加索引mongodb,添加索引可以提高select语句的性能吗
- chatgpt训练小黑子,小黑tt仔
- mysql集群怎么访问 mysql集群部署方式
- 包含jQuery.post延时的词条
- 日本食物经营游戏,日式经营养成游戏
- 钉钉是否能录屏直播,钉钉是否能录屏直播回放
- php导入数据 php导入数据库 纯文本 忽略空格