Golang语言之Channel通信,并发编程
1.Go语言特点
Go是一种静态强类型的开源语言,诞生于2009年,是非常年轻的一门语言其主要目标时“兼具Python等动态语言的开发速度,同时又具备想C语言C++的安全性与应能”,其中最大的特点(优势)就是并发编程
不同于大多编程语言的多线程,golang的并发执行单元是一种称之为goroutine的携程,由于绝大部分语言在其共享数据时会用到并发锁,再加上GC,其执行效率多多少少会受到影响,golang的并发编程简单。
- channel的使用——并发编程
ch := make(chan int)
这种是无缓冲的channel,一旦goroutine向管道内发送数据,那么当前的goroutine会被阻塞,直到其他的携程消费了管道里的数据才能正常运行。
ch := make(chan int, 2)
这种是有缓存的管道,与上面相比增加以一个uint型参数表示缓存容量,表示可并发执行的最大数量,只要当前channel类的元素总数不大于可缓冲容量,则当前的协程就不会阻塞住。
*注意:管道的出入方式与出弹栈有所不同,前者时先入先出而后者是先入后出(如下图)
2.1多个goroutine协同
多个写成最后汇总至结果
package main
func main() {
println("start main")
ch := make(chan int)
varresult int
go func() {
println("come into goroutine1")
varr int
fori := 1;i <= 10; i++ {
r += i
}
ch <- r
}()
go func() {
println("come into goroutine2")
varr int = 1
fori := 1;i <= 10; i++ {
r *= i
}
ch <- r
}()
go func() {
println("come into goroutine3")
ch <- 11
}()
fori := 0;i < 3; i++ {
result += <-ch
}
close(ch)
println("result is:", result)
println("end main")}
其执行结果如下:
start main
come into goroutine3
come into goroutine2
come into goroutine1
result is: 3628866
end main
*从执行效率看go语言的并发效率要比Java和C的高出不少,在上述代码中三个go func并发执行,并且互不干涉(这里还没有涉及到互斥锁)最终输出的顺序还没有混乱。
2.2 channel底层原理
再往下深究至源码 channel返回类型hchan结构体,如下图
type hchan struct {
qcount uint // channel 里的元素计数
dataqsiz uint // 可以缓冲的数量,如 ch := make(chan int, 10)。 此处的 10 即 dataqsiz
elemsize uint16 // 要发送或接收的数据类型大小
buf unsafe.Pointer // 当 channel 设置了缓冲数量时,该 buf 指向一个存储缓冲数据的区域,该区域是一个循环队列的数据结构
closed uint32 // 关闭状态
sendx uint // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已发送数据的索引位置
recvx uint // 当 channel 设置了缓冲数量时,数据区域即循环队列此时已接收数据的索引位置
recvq waitq // 想读取数据但又被阻塞住的 goroutine 队列
sendq waitq // 想发送数据但又被阻塞住的 goroutine 队列
lock mutex
...
}
该结构体中详细定义了管道内的各种操作 channel再进行数据写入写出时会有缓冲设置以及无缓冲的设置其异同如下
无缓冲channel
先写再读
由于 channel 是无缓冲的,所以 G1 暂时被挂起在队列里(由结构体中sendq字段接收),然后 G1 调用了 gopark字段 休眠了起来。接着,又有协程来channel读取数据了:
先读再写
如下图:
此时G1被暂时性挂起,等待进入channel
G2在进入管道时发现前面有协程存在,于是给G1发讯息,等待下次被调。
如下图:
作者:吴韵寰
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律