Channel 使用事项和注意细节

(1)channel 可以声明为只读,或者只写性质
(2)channel 只读和只写的最佳实践案例

在默认情况下,管道是双向管道,即可读可写。

var ch chan intfunc main() {//声明为只写管道var chan1 chan<- intchan1 = make(chan int, 3)fmt.Println(chan1)//声明为只读var chan2 <-chan intchan2 = make(chan int, 3)fmt.Println(chan2)
}

下面是只读,只写管道,可以有效的预防我们误操作。相当于将可读可写管道将只读的功能封装起来了,不给你使用,但是类型依然是chan int类型。

 

 

 select + channel  示例


使用select可以解决从管道取数据的阻塞问题【案例演示】

假设要从网上下载一个文件,我启动了 3 个 goroutine 进行下载,并把结果发送到 3 个 channel 中。其中,哪个先下载好,就会使用哪个 channel 的结果。

在这种情况下,如果我们尝试获取第一个 channel 的结果,程序就会被阻塞,无法获取剩下两个 channel 的结果,也无法判断哪个先下载好。这个时候就需要用到多路复用操作了,在 Go 语言中,通过 select 语句可以实现多路复用,其语句格式如下:

select {
case i1 = <-c1://todo
case c2 <- i2://todo
default:// default todo
}

整体结构和 switch 非常像,都有 case 和 default,只不过 select 的 case 是一个个可以操作的 channel。

小提示:多路复用可以简单地理解为,N 个 channel 中,任意一个 channel 有数据产生,select 都可以监听到,然后执行相应的分支,接收数据并处理。

有了 select 语句,就可以实现下载的例子了,如下面的代码所示:

func main() {//声明三个存放结果的channelfirstCh := make(chan string)secondCh := make(chan string)threeCh := make(chan string)//同时开启3个goroutine下载go func() {firstCh <- downloadFile("firstCh")}()go func() {secondCh <- downloadFile("secondCh")}()go func() {threeCh <- downloadFile("threeCh")}()//开始select多路复用,哪个channel能获取到值,就说明哪个最先下载好,就用哪个。select {case filePath := <-firstCh:fmt.Println(filePath)case filePath := <-secondCh:fmt.Println(filePath)case filePath := <-threeCh:fmt.Println(filePath)}
}func downloadFile(chanName string) string {//模拟下载文件,可以自己随机time.Sleep点时间试试time.Sleep(time.Second)return chanName+":filePath"
}

如果这些 case 中有一个可以执行,select 语句会选择该 case 执行,如果同时有多个 case 可以被执行,则随机选择一个,这样每个 case 都有平等的被执行的机会。如果一个 select 没有任何 case,那么它会一直等待下去。

---------------------------------------------------------------------------------------------------------------------------

要从管道当中读取数据需要close这个管道,不去close这个管道去遍历的时候,管道会阻塞,如果阻塞在main协程里面会发生死锁。

package mainimport ("fmt""time"
)func main() {//使用select可以解决从管道当中读取数据阻塞的问题//1.定义一个管道 10个数据intinitChan := make(chan int, 10)for i := 0; i < 5; i++ {initChan <- i}//2.定义一个管道 5个数据stringstringChan := make(chan string, 5)for i := 0; i < 5; i++ {stringChan <- "hello" + fmt.Sprintf("%d", i)}//传统的方法在遍历管道的时候如果不关闭会阻塞导致死锁//在实际开发过程中,可能无法确定什么时候关闭该管道//可以使用select的方式可以解决for {select {//如果管道一直没有关闭,也不会一直阻塞在这里导致死锁// 它会自动的到下一个case匹配,不依赖关闭case v := <-initChan:time.Sleep(time.Second * 1)fmt.Printf("从intchan读取了数据%d\n", v)case v := <-stringChan:time.Sleep(time.Second * 1)fmt.Printf("从stringChan读取了数据%s\n", v)default:time.Sleep(time.Second * 1)fmt.Println("都取不到了,不玩了,这里可以加入业务逻辑")}}
}从intchan读取了数据0
从intchan读取了数据1
从intchan读取了数据2
从intchan读取了数据3
从intchan读取了数据4
从stringChan读取了数据hello0
从stringChan读取了数据hello1
从stringChan读取了数据hello2
从stringChan读取了数据hello3
从stringChan读取了数据hello4
都取不到了,不玩了,这里可以加入业务逻辑
都取不到了,不玩了,这里可以加入业务逻辑
都取不到了,不玩了,这里可以加入业务逻辑
都取不到了,不玩了,这里可以加入业务逻辑

如果是在函数里面,直接使用return,那么就直接退出协程的函数。


4)goroutine中使用recover,解决协程中出现panic,导致程序崩溃问题.【案例演示】
说明:如果我们起了一个协程,但是这个协程出现了panic,如果我们没有捕获这个panic,就会造成整个程序崩溃,这时我们可以在goroutine中使用recover来捕获panic,进行处理,这样即使这个协程发生的问题,但是主var mapl map[string]string线程仍然不受影响,可以继续执行。map1["nol”]="tom"
 

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

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

相关文章

R2 score

R2 score is a criteria for linear model. R 2 1 − S S E S S T R^2 1 - \frac{SSE}{SST} R21−SSTSSE​ where, S S E SSE SSE is the residual sum of squares S S E ∑ i 1 n ( y ^ i − y i ) 2 SSE \sum_{i1}^n (\hat y_i - y_i)^2 SSEi1∑n​(y^​i​−yi​)2 S…

【中小型企业网络实战案例 五】配置可靠性和负载分担

【中小型企业网络实战案例 三】配置DHCP动态分配地址-CSDN博客 【中小型企业网络实战案例 四】配置OSPF动态路由协议 【中小型企业网络实战案例 二】配置网络互连互通-CSDN博客 【中小型企业网络实战案例 一】规划、需求和基本配置_大小企业网络配置实例-CSDN博客 配置VRRP联…

跨境电商卖家一般用海外云手机做什么?

近些年&#xff0c;海外云手机在跨境电商领域已经逐渐流行开来&#xff0c;但是对于许多人来说海外云手机还是比较陌生&#xff0c;它有什么作用&#xff1f;它可以用于哪些场景&#xff1f;在本文中&#xff0c;我们将详细跨境电商卖家一般是怎样使用海外云手机的。 1. 海外网…

单片机的存储、堆栈与程序执行方式

一、单片机存储区域 如图所示位STM32F103ZET6的参数&#xff1a; 单片机的ROM&#xff08;内部FLASH&#xff09;&#xff1a;512KB&#xff0c;用来存放程序代码的空间。 单片机的RAM&#xff1a;64KB&#xff0c;一般都被分配为堆、栈、变量等的空间。 二、堆和栈的概念 …

Linux shell编程学习笔记38:history命令

目录 0 前言 1 history命令的功能、格式和退出状态1.1 history命令的功能1.2 history命令的格式1.3退出状态2 命令应用实例2.1 history&#xff1a;显示命令历史列表2.2 history -a&#xff1a;将当前会话的命令行历史追加到历史文件~/.bash_history中2.3 history -c&#xf…

Leetcode 2983. Palindrome Rearrangement Queries

Leetcode 2983. Palindrome Rearrangement Queries 1. 解题思路2. 代码实现 题目链接&#xff1a;2983. Palindrome Rearrangement Queries 1. 解题思路 这道题看了一下&#xff0c;截至我写的时候&#xff0c;只有103个大佬给出了这个题目的解答&#xff0c;而且这次的竞赛…

Go语言中的HTTP重定向

大家好&#xff0c;我是你们可爱的编程小助手&#xff0c;今天我们要一起探讨如何使用Go语言实现HTTP重定向&#xff0c;让我们开始吧&#xff01; 大家都知道&#xff0c;网站开发中有时候需要将用户的请求从一个URL导向到另一个URL。比如说&#xff0c;你可能想将旧的URL结构…

Redis 数据结构和常用命令

* 代表多个&#xff0c;&#xff1f;代表一个 &#xff08;不用全部敲出来&#xff0c;按住tab可以自动补全&#xff09; -2是无效&#xff0c;-1是永久有效 &#xff1b;贴心小提示&#xff1a;内存非常宝贵&#xff0c;对于一些数据&#xff0c;我们应当给他一些过期时间&a…

attempted relative import beyond top-level package

attempted relative import beyond top-level package 这个错误通常发生在 Python 中尝试使用超出顶层包范围的相对导入时。Python 的相对导入是基于模块之间的相对位置进行的&#xff0c;因此&#xff0c;如果相对导入超出了顶层包的范围&#xff0c;就会报这个错误。 解决方法…

计算机组成原理-总线概述

文章目录 总线简图总线的物理实现总览总线定义总线的特性总线的分类按数据格式分类串行总线并行总线 按总线功能分类注意系统总线的进一步分类 总线的结构单总线的机构双总线的结构三总线的结构四总线的结构 小结 总线简图 总线的物理实现 如果该为数据总线&#xff0c;那么当…

Hive详解、配置、数据结构、Hive CLI

一、Hive 认识 1. Hive 应用 问题&#xff1a;公司的经营状况&#xff1f; 主题一&#xff1a;财务现金流指标1.1&#xff1a;净现金流入/流出量指标1.2&#xff1a;现金转换周期预算执行状况指标2.1&#xff1a;预算内成本控制指标2.2&#xff1a;预算与实际支出的差异 主题…

图文证明 泰勒公式展开

泰勒公式 泰勒公式简单来说就是,可以用一个N次多项式来表示出一个连续可导的函数 f(x) 是一个用函数在某点的信息描述其附近取值的公式 第一步 思考 这是一个sin(x)的图像 用函数在原点的信息描述其附近取值 用一阶导数贴合: 直接用切线来贴合就好 画一个点(0,sin(0)除的切…

MySQL使用问题记录

在使用MybatisPlus做一个记录的查询&#xff0c;出现一个奇怪的错误&#xff0c;异常信息如下&#xff1a; line 1:136 mismatched input source expecting {!, ~, , -, ., (, {, ?, , TRUNCATE, POSITION, VIEW, VALUES, CASE, CAST, TRIM, SUBSTRING, LEFT, RIGHT, IF, NOT…

Nginx和OpenResty面试题及简单示例

简要解释Nginx的工作原理 Nginx的工作原理&#xff1a; Nginx采用事件驱动和异步非阻塞的架构。它通过一个主进程和多个工作进程处理客户端请求。当有新的请求到达时&#xff0c;主进程接受并分发请求给空闲的工作进程进行处理。Nginx使用高效的I/O多路复用机制&#xff0c;可…

[NISACTF 2022]babyupload

[NISACTF 2022]babyupload wp 信息搜集 进入页面&#xff1a; 尝试文件上传&#xff0c;但是各种后缀名我都试过了&#xff0c;过不去。 在源码中发现提示&#xff0c;存在 ./source 路径&#xff1a; 访问该路径得到源码&#xff1a; from flask import Flask, request, r…

《深入理解C++11:C++11新特性解析与应用》笔记六

第六章 提高性能及操作硬件的能力 6.1 常量表达式 6.1.1 运行时常量性与编译时常量性 大多数情况下&#xff0c;const描述的是运行时常量性&#xff0c;也即是运行时数据的不可更改性。但有时候我们需要的却是编译时的常量性&#xff0c;这是const关键字无法保证的。例如&am…

精品Nodejs实现的在线菜谱食谱美食学习系统的设计与实现

《[含文档PPT源码等]精品Nodejs实现的在线菜谱学习系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Windows…

day5--java基础编程:异常,内部类

6 异常 6.1 异常概述 出现背景&#xff1a; 在使用计算机语言进行项目开发的过程中&#xff0c;即使程序员把代码写得尽善尽美&#xff0c;在系统的运行过程中仍然会遇到一些问题&#xff0c;因为很多问题不是靠代码能够避免的&#xff0c;比如:客户输入数据的格式&#xff0c…

逆变器在光伏发电系统中的作用是什么?安装时应注意哪些事项?

在光伏发电系统中&#xff0c;逆变器是一个至关重要的组件&#xff0c;主要作用是什么&#xff1f; 1.是将直流电转换为交流电的关键&#xff1a;太阳能电池板所产生的电能是直流电&#xff0c;逆变器可将直流电转换为交流电&#xff0c;是的太阳能电池板所产生的电能可以被家…

技术博客官网也是一个不错的学习平台(第411篇)

技术博客官网也是一个不错的学习平台(第411篇) 今天的主题是OSPF 大纲 技术成就梦想51CTO-中国知名的数字化人才学习平台和技术社区 OSPF 概念型问题_wx655f0abb3511b的技术博客_51CTO博客 OSPF协议介绍及配置 - airoot - 博客园 (cnblogs.com) 一、OSPF概述 回顾一下距离矢…