首页 > 其他分享 >Go 语言入门 1-管道的特性及实现原理

Go 语言入门 1-管道的特性及实现原理

时间:2022-09-01 15:03:28浏览次数:75  
标签:协程 入门 队列 读写 元素 chan 管道 Go

入坑 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) // 输出

 

 

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

 

举个栗子

标签:协程,入门,队列,读写,元素,chan,管道,Go
From: https://www.cnblogs.com/guanjinglin/p/16646496.html

相关文章

  • 修改mongodb的缓存大小
    在admin下首先查询当前cache大小db.serverStatus().wiredTiger.cache['maximumbytesconfigured']/1024/1024/1024 方法一:修改配置文件mongod.conf添加内容如下s......
  • 给正在运行的mongodb启动添加配置文件
    因为一开始启动容器的时候就没有指定配置文件,无论怎么修改容器中的/etc/mongd.conf.org文件都无法生效所以直接修改启动脚本添加$@的参数实现1、复制容器中的文件/usr/lo......
  • 史上最全 Appium 自动化测试从入门到框架实战精华学习笔记(三)
    ⬇️点击“下方链接”,提升测试核心竞争力!>>更多技术文章分享和免费资料领取本系列文章汇总了从Appium自动化测试从基础到框架高级实战中,所涉及到的方方面面的知识点精华......
  • RabbitMQ 入门系列:10、扩展内容:延时队列:延时队列插件及其有限的适用场景(系列大结局)。
    系列目录RabbitMQ入门系列:1、MQ的应用场景的选择与RabbitMQ安装。RabbitMQ入门系列:2、基础含义:链接、通道、队列、交换机。RabbitMQ入门系列:3、基础含义:持久化、......
  • go map键类型小记
    一、Go语言map的键类型不可以是函数类型、字典类型和切片类型。因为map键值需要可以做hash操作,而func,map,slice不支持这些操作。 报错:  并且,一般Struct可以支持ha......
  • Rust 从入门到精通06-语句和表达式
    1、语句和表达式语句和表达式是Rust语言实现逻辑控制的基本单元。在Rust程序里面,语句(Statement)是执行一些操作但不返回的指令,表达式(Expressions)计算并产生一个值。表......
  • 小迪安全D1笔记:基础入门-概念名词
    title:小迪安全D1笔记:基础入门-概念名词author:TTdate:2022-09-01域名网站的地址名称,如www.baidu.com可在第三方平台进行注册,如阿里云、namesilo顶级/一级域名:......
  • sprinngboot+Mongodb
    参考:https://blog.csdn.net/m0_46742141/article/details/121845098 maven依赖<dependency><groupId>org.springframework.boot</groupId>......
  • Django国际化
    安装python环境并配置系统变量安装django:pipinstallDjangoCMD中输入django-admin 看看是否有命令提示输出,如果没有,将”xxxxx\Roaming\Python\Python39\Scripts”加......
  • MongoDB 实现中文全文搜索
    Prerequisite倒排索引是所有支持全文搜索的数据库的基础。比如iamironman和iwillbesoonback,欲查找be,先查第一句,再查第二局,这是正排;将每个单词提取出来形成一个......