入坑 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)  // 有缓冲管道

管道的读写是通过操作符: 「<-」控制的,管道在左边表示把右侧数据写入到管道中, 管道在右边表示读取管道数据赋值给左侧变量。

ch1 := make(chan string)  // 初始化ch1 <- "gjl";  // 把 gjl 字符串写入到管道中c := <- ch1;  // 读取管道数据并交给 c 变量fmt.Println(c) // 输出

同时也可以通过操作符来限制管道的读写权限。

举个栗子:

func ChanRW(ch chan int) {  // 可以读写}
func ChanR(ch <-chan int){  // 仅可以读}
func ChanW(ch chan<- int){ // 仅可以写}

注意:对于值为 nil 的管道, 无论读写都会使协程永久阻塞。

最后我们具体看一下管道发送和接收时的处理流程图, 用 processon 简单画一下图(最近沉迷练习画图 - -):

发送:

接收:

如果您在实际开发过程中遇到过 Python、数据库、爬虫、分布式、消息队列等方面的难题, 也欢迎在公众号或评论区留言, 我们一起探讨解决方案

如果本篇内容能够帮助到您, 希望您关注我的公众号: 「python 学习爱好者」, 希望与您一起共同成长~

Go 语言入门 1-管道的特性及实现原理的更多相关文章

  1. Go语言入门(一)特性、安装、环境搭建、第一个程序等

    Go语言是谷歌推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性.谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发Go,是因为过去10多年间软件开发的难度令人沮 ...

  2. GO 语言入门(一)

    GO 语言入门(一) 本文写于 2020 年 1 月 18 日 Go 由 Google 工程师 Robert Griesemer,Rob Pike 和 Ken Thompson 设计的一门编程语言,第 ...

  3. 《C语言入门1.2.3—一个老鸟的C语言学习心得》—清华大学出版社炮制的又一本劣书及伪书

    <C语言入门1.2.3—一个老鸟的C语言学习心得>—清华大学出版社炮制的又一本劣书及伪书 [薛非评] 区区15页,有80多个错误. 最严重的有: 通篇完全是C++代码,根本不是C语言代码. ...

  4. c语言入门教程 / c语言入门经典书籍

    用C语言开始编写代码初级:C语言入门必备(以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言的数 ...

  5. 【转】c语言入门教程 / c语言入门经典书籍

    用C语言开始编写代码 初级:C语言入门必备 (以下两本书任选一本即可) C语言是作为从事实际编程工作的程序员的一种工具而出现的,本阶段的学习最主要的目的就是尽快掌握如何用c语言编写程序的技能.对c语言 ...

  6. go语言入门

    Go语言最主要的特性: 自动垃圾回收 更丰富的内置类型 函数多返回值 错误处理 匿名函数和闭包 类型和接口 并发编程 反射 语言交互性 1.2.4 错误处理Go语言引入了3个关键字用 ...

  7. 《Ruby语言入门教程v1.0》学习笔记-01

    <Ruby语言入门教程v1.0> 编著:张开川 邮箱:kaichuan_zhang@126.com 想要学习ruby是因为公司的自动化测试使用到了ruby语言,但是公司关于ruby只给了一 ...

  8. PBFT概念与Go语言入门(Tendermint基础)

    Tendermint作为当前最知名且实用的PBFT框架,网上资料并不很多,而实现Tendermint和以太坊的Go语言,由于相对小众,也存在资料匮乏和模糊错漏的问题.本文简单介绍PBFT概念和Go语言 ...

  9. 使用Code First建模自引用关系笔记 asp.net core上使用redis探索(1) asp.net mvc控制器激活全分析 语言入门必学的基础知识你还记得么? 反射

    使用Code First建模自引用关系笔记   原文链接 一.Has方法: A.HasRequired(a => a.B); HasOptional:前者包含后者一个实例或者为null HasR ...

随机推荐

  1. JS:undefined number

    undefined数据类型:未定义属性 undefined 表示不含值 <script> var t1=""; var t2; if (t1===undefined) ...

  2. 修改jupyter notebook文件保存目录

    我们安装好jupyter notebook之后,打开的默认地址是在C盘,文件保存的文字也是C盘,会有其它乱七八糟的东西放一起,很不方便,所以可以换一个保存位置 1. 首先,在要存放文件的位置新建文件夹 ...

  3. 搭建ceph分布式文件系统

      1. 准备4台虚拟机 ceph 192.168.66.93 管理osd,mon节点 ceph-node1 192.168.66.94 osd节点 ceph-node2 192.168.66.95 ...

  4. linux下的nginx日志自动备份压缩--日志切割机

    部署完毕nginx之后,发现自己的/var/log/nginx/*log的日志不会压缩,一直都是一个文本写日志, 时间久了,日志文件内存过于增加,将会导致在日志添加过程效率降低,延长时间. 默认安装的 ...

  5. 018(Phone List)(字典树)

    题目:http://ybt.ssoier.cn:8088/problem_show.php?pid=1471 题目思路: 这不就是一个超级明显的字典树嘛 字典树,又称单词查找树,Trie树,是一种树形 ...

  6. Java开发学习(八)----IOC/DI配置管理第三方bean、加载properties文件

    前面的博客都是基于我们自己写的类,现在如果有需求让我们去管理第三方jar包中的类,该如何管理? 一.案例:数据源对象管理 本次案例将使用数据源Druid和C3P0来配置学习下. 1.1 环境准备 学习 ...

  7. 密码学系列之:使用openssl检测网站是否支持ocsp

    目录 简介 支持OCSP stapling的网站 获取服务器的证书 获取OCSP responder地址 发送OCSP请求 一个更加简单的方法 总结 简介 OCSP在线证书状态协议是为了替换CRL而提 ...

  8. 集合—collection、iterator遍历集合

    一.collection接口 1.collection常用方法 点击查看代码 @Test public void test(){ //contains() Collection coll = new ...

  9. Linux shell脚本进阶使用

    shell的循环控制语句 - continue:提前结束某次循环,重新开始下一次 - break:提前结束某层循环 范例: #求100以内的奇数和 #!/bin/bash sum=0 for i in ...

  10. 串口通信:接受数据(仿真task写法)

    1.功能描述 设计一个串口数据接收模块.能够以设定的波特率(与发射端口速率匹配)接收数据,并输出保存到一个寄存器中. 2.过程描述 ①边沿检测器,识别出起始位时让接收使能端有效.这里需要排除边沿脉冲的 ...