【Go】十八、管道

文章目录

  • 1、管道
  • 2、管道的定义
  • 3、管道的关闭
  • 4、管道的遍历
  • 5、管道 + 协程
  • 6、只读、只写管道
  • 7、管道的阻塞
  • 8、select

1、管道

  • channel
  • 本质是一个队列,先进先出
  • 自身线程安全,多协程访问时,不用加锁,channel本身就是线程安全的
  • 一个string的管道只能存放string类型数据

在这里插入图片描述

2、管道的定义

var  变量名  chan  数据类型
  • chan是管道的关键字
  • 数据类型,比如int类型的管道只能写入整数int
  • 管道是引用类型,必须初始化才能写入数据,即make后才能使用
  • 管道中不能存放大于容量的数据
  • 在没有使用协程的情况下,如果管道的数据已经全部取出,那么再取就会报错

示例:

package main
import("fmt"
)
func main(){//定义管道 、 声明管道 ---> 定义一个int类型的管道var intChan chan int//通过make初始化:管道可以存放3个int类型的数据intChan = make(chan int,3)//证明管道是引用类型:fmt.Printf("intChan的值:%v",intChan) // 0xc000112080//向管道存放数据:intChan<- 10num := 20intChan<- numintChan<- 40  //注意:不能存放大于容量的数据://intChan<- 80  //在管道中读取数据:num1 := <-intChannum2 := <-intChannum3 := <-intChanfmt.Println(num1)fmt.Println(num2)fmt.Println(num3)//注意:在没有使用协程的情况下,如果管道的数据已经全部取出,那么再取就会报错:num4 := <-intChanfmt.Println(num4)//输出管道的长度:fmt.Printf("管道的实际长度:%v,管道的容量是:%v",len(intChan),cap(intChan))
}

3、管道的关闭

使用内置函数close可以关闭管道,当管道关闭后,就不能再向管道写数据了,但是仍然可以从该管道读取数据

package main
import("fmt"
)
func main(){//定义管道 、 声明管道var intChan chan int//通过make初始化:管道可以存放3个int类型的数据intChan = make(chan int,3)//在管道中存放数据:intChan<- 10intChan<- 20//关闭管道:close(intChan)//再次写入数据:--->报错//intChan<- 30//当管道关闭后,读取数据是可以的:num := <- intChanfmt.Println(num)
}

4、管道的遍历

  • for
  • for-range

在遍历时,如果管道没有关闭,则报错:

在这里插入图片描述

package main
import("fmt"
)
func main(){//定义管道 、 声明管道var intChan chan int//通过make初始化:管道可以存放100个int类型的数据intChan = make(chan int,100)for i := 0;i < 100;i++ {intChan<- i}//在遍历前,如果没有关闭管道,就会出现deadlock的错误//所以我们在遍历前要进行管道的关闭close(intChan)//遍历:for-rangefor v := range intChan {fmt.Println("value = ",v)}
}

5、管道 + 协程

  • 开启一个writeData协程,向管道中写入50个整数.
  • 开启一个readData协程,从管道中读取writeData写入的数据

在这里插入图片描述

package main
import("fmt""time""sync"
)
var wg sync.WaitGroup //只定义无需赋值//写:
func writeData(intChan chan int){defer wg.Done()for i := 1;i <= 50;i++{intChan<- ifmt.Println("写入的数据为:",i)time.Sleep(time.Second)}//管道关闭:close(intChan)
}//读:
func readData(intChan chan int){defer wg.Done()//遍历:for v := range intChan{fmt.Println("读取的数据为:",v)time.Sleep(time.Second)}
}func main(){//主线程//写协程和读协程共同操作同一个管道-》定义管道:intChan := make(chan int,50)wg.Add(2)//开启读和写的协程:go writeData(intChan)go readData(intChan)//主线程一直在阻塞,什么时候wg减为0了,就停止wg.Wait()	
}

运行:
在这里插入图片描述

在没有使用协程的情况下,如果管道的数据已经全部取出,那么再取就会报错。所以上面即使写入后sleep两秒,读取也不会报错。

6、只读、只写管道

package main
import("fmt"
)
func main(){//默认情况下,管道是双向的--》可读可写://var intChan1 chan int//声明为只写:var intChan2 chan<- int  // 管道具备<- 只写性质intChan2 = make(chan int,3)intChan2<- 20//num := <-intChan2 报错fmt.Println("intChan2:",intChan2)//声明为只读:var intChan3 <-chan int// 管道具备<- 只读性质 if intChan3 != nil {	//非空num1 := <-intChan3fmt.Println("num1:",num1)}//intChan3<- 30 报错}

7、管道的阻塞

管道只写入数据,不读取,超过容量:

package main
import("fmt"_"time""sync"
)
var wg sync.WaitGroup //只定义无需赋值//写:
func writeData(intChan chan int){defer wg.Done()for i := 1;i <= 20;i++{   //超过容量管道的容量10intChan<- ifmt.Println("写入的数据为:",i)//time.Sleep(time.Second)}//管道关闭:close(intChan)
}func main(){//主线程//定义管道:intChan := make(chan int,10)wg.Add(1)//开启写的协程:go writeData(intChan)wg.Wait()	
}

在这里插入图片描述

改一下,写的快,读的慢:没报错,但很明显,写被影响了,到最后被动等读协程,读走一个,写协程才能继续写。

在这里插入图片描述

8、select

  • 从多个管道中进行非阻塞的选择
  • select同时监听多个管道的数据流通,并在其中任意一个管道有数据可读或者可写的时候做相应的处理
select {
case <- channel1:// 处理channel1的数据
case data := <- channel2:// 处理channel2的数据
case channel3 <- value:// 向channel3发送数据
default:// 当没有任何通道准备就绪时执行default块
}

按顺序检查有没那个case后面的管道是可读或者可写的,有则执行该case语句。如果多个case同时满足,Go会随机选择一个执行。

如果没有任何case语句满足条件,且存在default语句,则执行default块中的代码。如果没有default语句,则select语句会被阻塞,直到至少有一个case语句满足条件。

package main
import("fmt""time"
)
func main(){//定义一个int管道:intChan := make(chan int,1)go func(){time.Sleep(time.Second * 5)intChan<- 10}()//定义一个string管道:stringChan := make(chan string,1)go func(){time.Sleep(time.Second * 2)stringChan<- "msbgolang"}()//fmt.Println(<-intChan)//本身取数据就是阻塞的select{case v := <-intChan :fmt.Println("intChan:",v)case v := <-stringChan :fmt.Println("stringChan:",v)default:fmt.Println("防止select被阻塞")}
}

输出:

防止select被阻塞

上面两个case的协程都不能立即可读或可写,走了default。没有default,则输出:

msbgolang

因为其对应的管道阻塞时间短,2s后就可以读到了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/796724.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

练习 19 Web [BJDCTF2020]Easy MD5

如果你是第一批做这个题的&#xff0c;这道题一点也不easy 打开在前端代码里面看到&#xff0c;输入框输入的内容实际是’password’ 随意输入内容&#xff0c;查看响应header中的内容有一句SQL代码&#xff0c;可知我们要让password在md5后返回值为true 然后尬住&#xff…

蓝桥杯嵌入式(G431)备赛笔记——LED

目录 cubeMX配置&#xff1a; 代码模板&#xff1a; 注意&#xff1a; cubeMX配置&#xff1a; 原理图&#xff0c;其中PD2高电平使能锁存器&#xff0c;PC8-15默认给高电平&#xff0c;放置上电初始化LED亮 74HC573是八路输出锁存器 1脚是使能&#xff0c;低电平有效&#…

05-延迟任务精准发布文章

延迟任务精准发布文章 1)文章定时发布 2)延迟任务概述 2.1)什么是延迟任务 定时任务&#xff1a;有固定周期的&#xff0c;有明确的触发时间延迟队列&#xff1a;没有固定的开始时间&#xff0c;它常常是由一个事件触发的&#xff0c;而在这个事件触发之后的一段时间内触发…

深度剖析鞋服品牌商品数字化管理的重要性

随着信息技术的迅猛发展与市场竞争的加剧&#xff0c;鞋服品牌商品数字化管理的重要性愈发凸显。数字化管理不仅关乎企业运营效率的提升&#xff0c;更是品牌实现差异化竞争、提升顾客体验、构建智慧零售生态的关键所在。对于鞋服品牌企业而言&#xff0c;提升商品数字化管理的…

【Linux】环境基础开发工具使用——vim使用

Linux 软件包管理器 yum 什么是软件包 1.在 Linux 下安装软件 , 一个通常的办法是下载到程序的源代码 , 并进行编译 , 得到可执行程序 . 2.但是这样太麻烦了 , 于是有些人把一些常用的软件提前编译好 , 做成软件包 ( 可以理解成 windows 上的安装程序) 放在一个服务器…

深度学习-机器视觉part2

深度学习-机器视觉part2 文章目录 深度学习-机器视觉part2一、从卷积到卷积神经网络二、手撕卷积代码2.1 动机2.2 数据集2.3 卷积操作2.3.1 填充&#xff08;padding&#xff09;2.3.2 卷积块2.3.3 池化2.3.4 Softmax 2.4 完整CNN2.5 训练改进 三、经典CNN模型介绍四、CNN模型的…

ASP.Net添加Swagger注释

文章目录 Swagger添加Swagger注释 Swagger 添加Swagger注释 1、右击项目->选择属性->点击生成->输出&#xff0c;选中文档文件 2、配置服务 在program.cs 文件里配置SwaggerUI //增加项一 builder.Services.AddSwaggerGen(c> {c.SwaggerDoc("v1", ne…

如何将本地仓库放到远程仓库中

在我们仓库创建好之后&#xff0c;我们复制好ssh 接着我们需要使用git remote add<shortname><url>这个命令 shortname就是我们远程仓库的别名 接着使用git remote -v这个命令查看一下目前远程仓库的别名和地址 原本还有一个指令git branch -M main 指定分支的名…

软考高级架构师:嵌入式数据库概念和例题

作者&#xff1a;明明如月学长&#xff0c; CSDN 博客专家&#xff0c;大厂高级 Java 工程师&#xff0c;《性能优化方法论》作者、《解锁大厂思维&#xff1a;剖析《阿里巴巴Java开发手册》》、《再学经典&#xff1a;《Effective Java》独家解析》专栏作者。 热门文章推荐&am…

EXCEL地理数据处理工具(地图任务)

版本号 作者 修订内容 发布日期 1.0 小O 更新至0705版 2022-4-28 1.1 小O 更新至0772版 2024年4月3日 一、概述 小O地图EXCEL插件版提供基于EXCEL表格进行地理数据处理、地图可视化、地图绘图等功能&#xff0c;地理工具是用户使用频率很高的功能模块。地理工具能…

京东云服务器4核8G主机租用价格418元一年,1899元3年

京东云轻量云主机4核8G服务器租用价格418元一年&#xff0c;1899元3年&#xff0c;配置为&#xff1a;轻量云主机4C8G-180G SSD系统盘-5M带宽-500G月流量&#xff0c;京东云主机优惠活动 yunfuwuqiba.com/go/jd 可以查看京东云服务器详细配置和精准报价单&#xff0c;活动打开如…

Day108:代码审计-PHP模型开发篇MVC层动态调试未授权脆弱鉴权未引用错误逻辑

目录 案例1-Xhcms-动态调试-脆弱的鉴权逻辑 案例2-Cwcms-动态调试-未引用鉴权逻辑 案例3-Bosscms-动态调试-不严谨的鉴权逻辑 知识点&#xff1a; 1、PHP审计-动态调试-未授权安全 2、PHP审计-文件对比-未授权安全 3、PHP审计-未授权访问-三种形态 动态调试优点: 环境配置&…

BFS(扫雷游戏、Tokitsukaze and Development Task、全球变暖)

注&#xff1a;1. 列举搜索方位dx,dy 2. 借助队列queue<> 3. 出队&#xff0c;入队操作 题目1:P2670 [NOIP2015 普及组] 扫雷游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 代码&#xff1a; #include<bits/stdc.h> using namespace std; char c[105][105…

Linux--03---虚拟机网络配置、拍摄快照和克隆

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.虚拟机网络配置1.虚拟机的联网模式模式1 仅主机模式特点模式2 桥接模式特点模式3 NAT模式特点关于模式的选择 2. 修改网络配置信息3.修改虚拟机ens33网卡的网络配…

2. Django配置信息

第2章 Django配置信息 Django的配置文件settings.py用于配置整个网站的环境和功能, 核心配置必须有项目路径, 密钥配置, 域名访问权限, App列表, 中间件, 资源文件, 模板配置, 数据库的连接方式.* 项目运行时, 如果修改代码, 项目会自动检测发现改动后会重新运行, 除非报错否…

Tomcat管理配置

Tomcat管理配置 1 host-manager项目2 manager项目 Tomcat 提供了Web版的管理控制台&#xff0c;位于webapps目录下。Tomcat 提供了用于管理Host的host-manager和用于管理Web应用的manager。 1 host-manager项目 Tomcat启动之后&#xff0c;可以通过 http://localhost:8080/ho…

Android 的网络加载

发起网络请求的过程 当用户在应用程序中输入网址或关键字时&#xff0c;应用程序会发起网络请求。这个过程大致如下&#xff1a; 应用程序将请求发送到服务器&#xff0c;服务器返回响应数据。应用程序接收到响应数据后&#xff0c;将其转换为应用程序可识别的数据格式。应用…

qt-C++笔记之QLabel加载图片

qt-C笔记之QLabel加载图片 —— 2024-04-06 夜 code review! 文章目录 qt-C笔记之QLabel加载图片0.文件结构1.方法一&#xff1a;把图片放在项目路径下&#xff0c;在 .pro 文件中使用 DISTFILES添加图片文件1.1.运行1.2.qt_test.pro1.3.main.cpp 2.方法二&#xff1a;不在 .pr…

院内感染的相关因素分析(Boruta联合SHAP分析2)R

院内感染的相关因素分析&#xff08;Boruta联合SHAP分析2&#xff09;R 和鲸社区一键运行代码 院内感染是指住院患者在医疗机构内发生的感染&#xff0c;是医院管理中常见且严重的问题。院内感染不仅会延长患者住院时间&#xff0c;增加医疗费用&#xff0c;还会严重威胁患者生…

vim美化配置(懒人版)

文章目录 配置vim&#xff08;懒人版&#xff09;1.搜索资源2.安装3.自定义缩进4.卸载方法 配置vim&#xff08;懒人版&#xff09; 1.搜索资源 打开gitee&#xff0c;注意到上面的搜索框 搜索 vimforcpp 进入&#xff0c;找到安装方法中的链接 2.安装 复制粘贴到linux中的命…