golang学习笔记——将 channel 用作通信机制

文章目录

  • 将 channel 用作通信机制
  • Channel 语法
  • 无缓冲 channel
  • 缓冲 channels
    • channel 与 goroutine
    • 缓冲 channels 示例
    • 多路复用

将 channel 用作通信机制

golang学习笔记——将 channel 用作通信机制
golang学习笔记——并发计算斐波纳契数

Go 中的 channel 是 goroutine 之间的通信机制。 请记住 Go 的并发方法是:不是通过共享内存通信;而是通过通信共享内存。当你需要将值从一个 goroutine 发送到另一个时,可以使用通道。 让我们看看它们的工作原理,以及如何开始使用它们来编写并发 Go 程序。

Channel 语法

ch <- x // sends (or writes ) x through channel ch
x = <-ch // x receives (or reads) data sent to the channel ch
<-ch // receives data, but the result is discarded

关闭 channel

close(ch)

无缓冲 channel

使用 make() 函数创建 channel 时,会创建一个无缓冲 channel,这是默认行为。 无缓冲 channel 会阻止发送操作,直到有人准备好接收数据。

package mainimport ("fmt""net/http""time"
)func main() {start := time.Now()apis := []string{"https://mp.csdn.net/","https://dev.azure.com","https://api.somewhereintheinternet.com/","https://gitcode.net/",}ch := make(chan string)for _, api := range apis {go checkAPI(api, ch)}for i := 0; i < len(apis); i++ {fmt.Print(<-ch)}elapsed := time.Since(start)fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}func checkAPI(api string, ch chan string) {_, err := http.Get(api)if err != nil {ch <- fmt.Sprintf("ERROR: %s is down!\n", api)return}ch <- fmt.Sprintf("SUCCESS: %s is up and running!\n", api)
}

缓冲 channels

下面是一个理解有缓冲 channel 的简单示例

package mainimport ("fmt"
)func send(ch chan string, message string) {ch <- message
}func main() {size := 4ch := make(chan string, size)send(ch, "one")send(ch, "two")send(ch, "three")send(ch, "four")fmt.Println("All data sent to the channel ...")for i := 0; i < size; i++ {fmt.Println(<-ch)}fmt.Println("Done!")
}

输出

All data sent to the channel ...
one
two
three
four
Done!

试着将size改为2
重新运行程序时,将看到以下错误:

fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:
main.send(...)D:/golang2023/main.go:8
main.main()D:/golang2023/main.go:16 +0x97
exit status 2

channel 与 goroutine

channel 与 goroutine 有着紧密的联系。 如果没有另一个 goroutine 从 channel 接收数据,则整个程序可能会永久处于被阻止状态。 正如你所见,这种情况确实会发生。

缓冲 channels 示例

使用之前用于检查 API 的示例,并创建大小为 10 的缓冲通道

package mainimport ("fmt""net/http""time"
)func main() {start := time.Now()apis := []string{"https://management.azure.com","https://dev.azure.com","https://mp.csdn.net/","https://outlook.office.com/","https://api.somewhereintheinternet.com/","https://gitcode.net/",}ch := make(chan string, 10)for _, api := range apis {go checkAPI(api, ch)}for i := 0; i < len(apis); i++ {fmt.Print(<-ch)}elapsed := time.Since(start)fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}func checkAPI(api string, ch chan string) {_, err := http.Get(api)if err != nil {ch <- fmt.Sprintf("ERROR: %s is down!\n", api)return}ch <- fmt.Sprintf("SUCCESS: %s is up and running!\n", api)
}

多路复用

最后,让我们讨论如何使用 select 关键字与多个通道同时交互。 有时,在使用多个 channel 时,需要等待事件发生。 例如,当程序正在处理的数据中出现异常时,可以包含一些逻辑来取消操作。

select 语句的工作方式类似于 switch 语句,但它适用于 channel。 它会阻止程序的执行,直到它收到要处理的事件。 如果它收到多个事件,则会随机选择一个。

select 语句的一个重要方面是,它在处理事件后完成执行。 如果要等待更多事件发生,则可能需要使用循环。

让我们使用以下程序来看看 select 的运行情况:

package mainimport ("fmt""time"
)func process(ch chan string) {time.Sleep(3 * time.Second)ch <- "Done processing!"
}func replicate(ch chan string) {time.Sleep(1 * time.Second)ch <- "Done replicating!"
}func main() {ch1 := make(chan string)ch2 := make(chan string)go process(ch1)go replicate(ch2)for i := 0; i < 2; i++ {select {case process := <-ch1 :fmt.Println(process)case replicate := <-ch2 :fmt.Println(replicate)}}
}

输出

Done replicating!
Done processing!

请注意,replicate 函数首先完成,这就是首先在终端中看到其输出的原因。 main 函数存在一个循环,因为 select 语句在收到事件后立即结束,但我们仍在等待 process 函数完成。

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

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

相关文章

使用Pytorch从零开始构建DCGAN

在本文中&#xff0c;我们将深入研究生成建模的世界&#xff0c;并使用流行的 PyTorch 框架探索 DCGAN&#xff08;生成对抗网络 (GAN) 的一种变体&#xff09;的实现。具体来说&#xff0c;我们将使用 CelebA 数据集&#xff08;名人面部图像的集合&#xff09;来生成逼真的合…

网络安全等级保护收费标准?

不同省份价格会略有不同&#xff0c;二级等保一般不低于5万元;三级等保不低于9万元&#xff0c;个别省份也可能7万也能办理&#xff0c;根据企业实际情况和省市选定的代理机构确定。 等级保护二级? 第二级等保是指信息系统受到破坏后&#xff0c;会对公民、法人和其他组织的合…

刷到一个很骚气的 Go 错误处理新提案

在比较一段长的时间里&#xff0c;Go 的错误处理已经没有什么特别的进展和新改进了。看着已经到了瓶颈期。 今天在 GitHub 上学习时&#xff0c;看到 Go 社区里有人提了个错误处理的优化提案《proposal: Go 2: Error-Handling Paradigm with !err Grammar Sugar》&#xff0c;…

《YOLOv8创新改进》专栏指导书册 手把手创新教程

&#x1f680;&#x1f680;&#x1f680;YOLOv8改进专栏&#xff1a;http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8&#xff0c;从入门到创新&#xff0c;轻轻松松搞定科研&#xff1b; 本专栏为订阅者提供答疑服务&#xff0c;每一篇提供源代码和详细的每一个步骤改进地方。…

Navicat 技术指引 | 适用于 GaussDB 的模型功能

Navicat Premium&#xff08;16.2.8 Windows版或以上&#xff09; 已支持对 GaussDB 主备版的管理和开发功能。它不仅具备轻松、便捷的可视化数据查看和编辑功能&#xff0c;还提供强大的高阶功能&#xff08;如模型、结构同步、协同合作、数据迁移等&#xff09;&#xff0c;这…

工业交换机具备哪些功能?

在工业网络中&#xff0c;工业交换机起着至关重要的作用&#xff0c;具备多样功能和广泛的应用。 1、工业交换机的作用是实现不同网络设备之间的互联。它能够连接各种不同类型的设备&#xff0c;如计算机、服务器、传感器和监控设备&#xff0c;实现设备间的相互通信和数据传输…

应用高斯高通滤波器提取图像轮廓

任务要求&#xff1a; 图为HALCON中的例图“tooth_rim”&#xff0c;请用高斯高通滤波器提取图像的轮廓。 任务分析&#xff1a; 图像的边缘对应频谱的高频部分&#xff0c;可以通过构造一个高频滤波器&#xff0c;过滤掉图像的低频部分&#xff0c;从而得到图像的边缘。HALC…

苹果怎么关闭悬浮球?让我来解答您的疑惑!

悬浮球是苹果设备上的一种可进行自定义的快捷操作功能&#xff0c;它可以位于手机屏幕的任意位置&#xff0c;以浮动的方式显示。然而&#xff0c;有时候悬浮球对某些朋友来说可能会变得多余&#xff0c;那么苹果怎么关闭悬浮球呢&#xff1f;接下来&#xff0c;小编将为大家揭…

docker compose搭建渗透测试vulstudy靶场示例

前言 渗透测试&#xff08;Penetration test&#xff09;即网络安全工程师/安全测试工程师/渗透测试工程师通过模拟黑客&#xff0c;在合法授权范围内&#xff0c;通过信息搜集、漏洞挖掘、权限提升等行为&#xff0c;对目标对象进行安全测试&#xff08;或攻击&#xff09;&am…

【快应用】小程序转快应用中如何获取用户已授权的权限

【关键词】 权限、SystemInfo、setting 【问题背景】 小程序转快应用&#xff0c;用户在使用快应用的过程中如果产生了一些授权行为&#xff0c;开发者是否有办法去收集到用户已经授权过的权限呢&#xff0c;从而进行更好管理呢&#xff1f; 【解决方案】 小程序转快应用中是…

详解——菱形继承及菱形虚拟继承

目录 一&#xff0c;菱形继承 1.1单继承 1.2多继承 1.3菱形继承 1.4菱形继承的问题 1.5虚拟继承解决数据冗余和二义性的原理 二.继承的总结和反思 一&#xff0c;菱形继承 C三大特性——继承-CSDN博客 1.1单继承 单继承&#xff1a;一个子类只有一个直接父类时称这个继…

javaScript解决手机浏览器下载为图片之后,图片漆黑无法保存的问题

pc端能正常下载图片并查看 手机移动端下载的图片全是黑色的并且无法保存&#xff0c;这个问题可能与移动浏览器的安全策略有关 解决办法&#xff1a;使用Blob对象和createObjectURL方法来创建一个临时URL&#xff0c;然后将其赋给链接的href属性下载&#xff1a; // 转blob函…

anaconda安装配置

创建分区 conda create -n cpu 安装Cpu版本 https://pytorch.org/ conda install pytorch torchvision torchaudio cpuonly -c pytorch 激活环境 conda activate cpu 验证 退出当前分区 conda deactivate 安装GPU版本 创建分区conda create -n gpu 激活环境 conda…

Java面向对象(高级)-- final关键字的使用

文章目录 一、 final的意义二、 final的使用&#xff08;1&#xff09; final修饰类&#xff08;2&#xff09; final修饰方法&#xff08;3&#xff09; final修饰变量1. 修饰成员变量1.1 举例11.2 举例2 2. 修饰局部变量2.1 举例12.2 举例2 &#xff08;4&#xff09;final搭…

java协程操作mysql数据库

我的项目&#xff1a; nanshaws/nettyWeb: 复习一下netty&#xff0c;并打算做一个web项目出来 (github.com) 最近在项目中分别添加了虚拟线程操作mysql数据库&#xff0c;和用协程操作mysql数据库 同理先跟我这个博客操作一下前面的&#xff1a;就单纯代码的时候进行修改&a…

TikTok与精神健康:社交媒体在压力时代的作用

在当今数字化和社交化的时代&#xff0c;社交媒体已成为人们生活中不可或缺的一部分。其中&#xff0c;TikTok作为一款备受欢迎的短视频应用&#xff0c;不仅改变了人们的娱乐方式&#xff0c;也对精神健康产生了深远的影响。 本文将深入探讨TikTok在压力时代对精神健康的作用…

2023年中国油田工程建设市场规模现状及行业竞争分析[图]

油田工程建设是在确定油气田有开发生产的价值的基础上&#xff0c;进行系统的工程建设&#xff0c;油田工程建设包括井场建设、管道施工、土石方工程、道路建设及绿化等服务。 油田工程建设主要内容 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; 油田服务…

oapi-codegen 安装和使用

背景描述 oapi-codegen 是代码自动生成工具&#xff0c;其大致逻辑是&#xff1a;&#xff08;1&#xff09;编写遵循 openAPI 规范的 yaml 格式 api 接口文档&#xff1b;&#xff08;2&#xff09;使用 oapi-codegen 使用 yaml 文件生成 gin 框架的 server 端代码。 除此以…

编辑 | 古代汉语知识

文章目录 文字通假字古今字异体字&#xff08;了解&#xff09; 词汇古汉语中的单音词与双音词&#xff08;掌握&#xff09;词的本义与引申义的特点和主要差异&#xff08;掌握&#xff09;词的古义与今义的特点和主要差异&#xff08;掌握&#xff09;与现代汉语用法相同与现…

反向传播BP算法

神经网络的反向传播 反向传播机制与代码微分引擎与代码原理阐述 如需转载&#xff0c;请注明出处&#xff01; 如有帮助点赞收藏关注&#xff01; 反向传播机制与代码 这里主要介绍反向传播是如何运作的&#xff0c;代码中会加注释&#xff0c;便于大家理解。 在训练神经网络时…