IT评测·应用市场-qidao123.com技术社区
标题:
Go 语言入门 1-管道的特性及实现原理
[打印本页]
作者:
曂沅仴駦
时间:
2022-9-16 17:25
标题:
Go 语言入门 1-管道的特性及实现原理
入坑 go 也快一年了,从今天开始会定期分享一下 Go 语言学习过程中的一些基础知识。
go 语言中的管道, 主要是用于协程之间的通信, 比 UNIX 的管道更加轻量和易用。
我们先看一下管道的
数据结构:
type hchan struct { gcount uint // 环形队列剩余元素个数 dataqsiz uint // 环形队列长度 buf unsafe.Pointer // 环形队列指针 elemsize uint16 // 每个元素大小 closed uint32 // 标识关闭状态 elemtype *_type // 元素类型 sendx uint // 下一个元素写入时的下标 recvx uint // 下一个元素读取时的下标 recvq waitq // 等待读消息的队列 sendq waitq // 等待写消息的队列 lock mutex // 互斥锁, 保障管道无法并发读写}
复制代码
源码链接:
https://github.com/golang/go/blob/0d0193409492b96881be6407ad50123e3557fdfb/src/runtime/chan.go#L33
通过上述数据结构, 我们可以理解管道是由三部分组成的:
环形队列
读写等待队列
队列元素基本信息
从管道读取数据时, 如果管道
缓冲区为空
或者
没有缓冲区
, 那么当前协程就会阻塞, 然后
放入 recvq 队列
中。
往管道写入数据时, 如果管道
缓冲区为空
或者
缓冲区满了
, 那么当前协程就会阻塞, 然后
放入 sendq 队列
中。
读阻塞的协程会被新来的写数据的协程唤醒。
写阻塞的协程会被新来的读数据的协程唤醒。
同时上述数据结构中, 我们可以看到一个管道中只能传递一种元素类型。 如果想数据类型动态化, 可以传递 interface。
管道的操作:
初始化
有两种方式:
变量声明:
var ch chan int // 声明一个新的管道
复制代码
使用 make:
ch1 := make(chan string) // 无缓冲管道ch1 := make(chan string 3) // 有缓冲管道
复制代码
管道的读写是通过操作符: 「
欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/)
Powered by Discuz! X3.4