Channel

Go 中 channel 中用法和实现总结 以下分析和源码都是基于 go1.17 版本 channel 简介 Go 语言的基础类型之一, 用于在协程与协程之间传递数据 (channel 数据的传输方式也是值传递, Go语言的数据传输只有值传递) Do not communicate by sharing memory; instead, share memory by communicating. channel 保证: 数据的先入先出 并发情况下的数据安全 已经关闭的 channel 不可重开 channel 的实现 channel 在内部实现的结构体为 runtime.hchan 有一个环形链表, 暂存要传输的数据. 无 buffer 的channel 该队列长度为0, 所以不进行数据缓冲. 有一把互斥锁mutex, 在并发情况下, 保护自身数据结构的一致性 有两个协程等待链表, 用于挂载因为发送/接收而阻塞在该 channel 上的协程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type hchan struct { qcount uint // 当前 buffer 中有暂存着多少个数据 dataqsiz uint // 环形数组的buffer个数, 由 make 初始化的时候第二个参数容量决定的 buf unsafe.Pointer // 环形数组开始地址 elemsize uint16 // channel 传输的元素大小, 用于计算内存大小 closed uint32 // channel 是否已经关闭 0未关闭, 非0关闭 elemtype *_type // element type # channel 元素的类型 sendx uint // 环形链表中, 发送数据存储的下标 recvx uint // 环形链表中, 接受数据获取数据的下标 recvq waitq // 阻塞在该 channel 等待获取数据的 Groutine 列表 sendq waitq // 阻塞在该 channel 等待写入数据的 Groutine 列表 lock mutex // # 互斥锁 用于保护自身数据变更 } 初始化 channel 传递的元素不能太大 如果是空结构体或者无缓冲队列, 是不需要分配环形队列内存 如果传递数据类型有内含指针, 需要将环形队列分配到堆上 内部实现函数runtime.makechan ...

<span title='2022-04-02 10:09:22 +0800 +0800'>April 2, 2022</span>&nbsp;·&nbsp;11 min&nbsp;·&nbsp;潜水员

Go 常用的命令汇总

工具分类 go build 编译源代码文件 -race 编译出的目标程序,会启用数据竞争检测 go doc 查看包的文档(定义于doc.go的注释中), 于包中公开的函数签名 example 1 2 3 go doc go doc encoding/json go env 查看 go 相关的环境变量 1 2 3 4 5 # -w 设置环境变量 go env -w GOPAHT='/some/path' # -u 恢复成默认设置 go env -u GOPATH go generate 扫描文件中的指令并执行, 相关指令目的应该是“生成或者修改源文件” 注释的指令格式 //go:generate command argument... ps: wire 也是利用命令, 生成依赖注入文件 go get 管理当前module依赖 1 2 3 4 5 6 7 8 # 添加依赖包 go get example.com/pkg # 指定包版本 go get example.com/pkg@1.2.3 # 移除依赖 go get example.com/pkg@none go install 获取包文件,并编译和安装。可执行文件编译到$GOBIN路径下, 包文件编译到$GOPATH/pkg ...

<span title='2022-04-01 19:56:59 +0800 +0800'>April 1, 2022</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;潜水员