入坑 go 也快一年了,从今天开始会定期分享一下 Go 语言学习过程中的一些基础知识。
go 语言中的管道, 主要是用于协程之间的通信, 比 UNIX 的管道更加轻量和易用。
我们先看一下管道的 数据结构:
<span class="code-snippet_outer"><span class="code-snippet__attribute">type hchan struct {</span></span>
<span class="code-snippet_outer">  <span class="code-snippet__attribute">gcount   uint  // 环形队列剩余元素个数</span></span>
<span class="code-snippet_outer">  dataqsiz uint // 环形队列长度</span>
<span class="code-snippet_outer">  buf      unsafe.Pointer // 环形队列指针</span>
<span class="code-snippet_outer">  elemsize uint16 // 每个元素大小</span>
<span class="code-snippet_outer">  closed   uint32  // 标识关闭状态</span>
<span class="code-snippet_outer">  elemtype *_type  // 元素类型</span>
<span class="code-snippet_outer">  sendx    uint   // 下一个元素写入时的下标</span>
<span class="code-snippet_outer">  recvx    uint   // 下一个元素读取时的下标</span>
<span class="code-snippet_outer">  recvq    waitq // 等待读消息的队列</span>
<span class="code-snippet_outer">  sendq    waitq // 等待写消息的队列</span>
<span class="code-snippet_outer">  lock     mutex  // 互斥锁, 保障管道无法并发读写</span>
<span class="code-snippet_outer">}</span>
源码链接:
https://github.com/golang/go/blob/0d0193409492b96881be6407ad50123e3557fdfb/src/runtime/chan.go#L33
通过上述数据结构, 我们可以理解管道是由三部分组成的:
环形队列
读写等待队列
队列元素基本信息
从管道读取数据时, 如果管道 缓冲区为空或者 没有缓冲区, 那么当前协程就会阻塞, 然后 放入 recvq 队列中。
往管道写入数据时, 如果管道 缓冲区为空或者 缓冲区满了, 那么当前协程就会阻塞, 然后 放入 sendq 队列中。
读阻塞进程将被写入数据的新进程唤醒。
[En]
The read blocking process will be awakened by the new process of writing data.
写入阻塞进程将被读取数据的新进程唤醒。
[En]
The write blocking process will be awakened by the new process of reading data.
同时上述数据结构中, 我们可以看到一个管道中只能传递一种元素类型。 如果想数据类型动态化, 可以传递 interface。
管道的操作:
初始化有两种方式:
变量声明:
<span class="code-snippet_outer"><span class="code-snippet__keyword">var ch chan int  </span></span>
使用 make:
<span class="code-snippet_outer"><span class="code-snippet__attribute">ch1 := make(chan string) // 无缓冲管道</span></span>
<span class="code-snippet_outer">ch1 := make(chan string <span class="code-snippet__number">3) // 有缓冲管道</span></span>
管道的读写是通过操作符: 「
Original: https://www.cnblogs.com/guanjinglin/p/16646496.html
Author: 关靖霖
Title: Go 语言入门 1-管道的特性及实现原理
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/498529/
转载文章受原作者版权保护。转载请注明原作者出处!