go语言中的通道(channel)详解
在 Go 语言中,通道(channel) 是一种用于在 goroutine(协程)之间传递数据的管道。通道具有类型安全性,即它只能传递一种指定类型的数据。通道是 Go 并发编程的重要特性,能够让多个 goroutine 之间同步地通信,并确保数据传递的安全性。
以下是关于 Go 语言通道的详细介绍:
1. 通道的创建
要创建一个通道,使用内置的 make
函数:
ch := make(chan int) // 创建一个整型的通道
可以创建以下两种通道:
- 无缓冲通道:直接用
make(chan T)
创建,是默认通道类型。- 发送和接收操作必须同步,即发送方和接收方必须同时准备好。
- 缓冲通道:用
make(chan T, capacity)
创建,capacity
是通道的缓冲区大小。- 缓冲通道允许在缓冲区未满时发送数据,在未空时接收数据。
ch := make(chan int, 3) // 创建一个缓冲容量为 3 的整型通道
2. 通道的发送和接收
在通道中传递数据时,使用 <-
操作符。发送和接收操作会根据通道的类型(无缓冲或有缓冲)来同步或异步地完成。
- 发送数据到通道:
ch <- 42 // 将 42 发送到通道 ch
- 从通道接收数据:
value := <-ch // 从通道 ch 中接收数据并赋值给变量 value
通道的接收操作会阻塞,直到有数据发送进来;发送操作会阻塞,直到有接收方来取数据(无缓冲情况下)。
3. 通道的关闭
可以用 close
函数关闭通道,以通知接收方不再有数据传入。关闭通道后继续发送数据会导致运行时错误,但可以继续接收未被接收的数据。
close(ch)
使用 for
循环结合 range
可以遍历通道中的数据,直到通道关闭:
for value := range ch {fmt.Println(value)
}
4. 单向通道
在函数参数中,可以限制通道的方向,使其成为单向通道:
- 发送通道:只能发送数据
func sendData(ch chan<- int) { ch <- 42 }
- 接收通道:只能接收数据
func receiveData(ch <-chan int) { value := <-ch fmt.Println(value) }
单项通道用法示例:
package mainimport ("fmt""time"
)// 生产者函数,接收一个只能发送数据的通道
func producer(ch chan<- int) {for i := 1; i <= 5; i++ {fmt.Printf("Producer: Sending %d\n", i)ch <- i // 向通道发送数据time.Sleep(time.Second) // 模拟生产的耗时}close(ch) // 生产结束后关闭通道
}// 消费者函数,接收一个只能接收数据的通道
func consumer(ch <-chan int) {for value := range ch {fmt.Printf("Consumer: Received %d\n", value) // 从通道接收数据time.Sleep(2 * time.Second) // 模拟消费的耗时}fmt.Println("Consumer: Channel closed")
}func main() {ch := make(chan int)go producer(ch) // 启动生产者go consumer(ch) // 启动消费者time.Sleep(10 * time.Second) // 等待足够时间以观察输出
}
5. 使用 select 语句处理多通道
Go 提供了 select
语句来处理多通道的并发操作。select
允许在多个通道操作之间进行选择,第一个准备好的通道会被执行,其他通道则被忽略。
select {
case msg1 := <-ch1:fmt.Println("Received", msg1)
case ch2 <- msg2:fmt.Println("Sent", msg2)
default:fmt.Println("No channel ready")
}
6. 常见通道操作示例
- 实现生产者-消费者模型:生产者往通道里发送数据,消费者从通道中接收数据。
- 任务分发和结果收集:可以使用多个通道在不同的 goroutine 之间传递任务和收集结果。
7. 注意事项
- 尽量避免在未关闭的通道上使用
range
,否则可能会导致死锁。 - 通道的发送和接收操作是阻塞的,要小心处理以防止 goroutine 的阻塞和死锁问题。
简单示例
下面是一个简单的例子,展示如何在多个 goroutine 中使用通道同步:
package mainimport ("fmt""time"
)func worker(id int, ch chan int) {for {value, ok := <-chif !ok {fmt.Printf("Worker %d: Channel closed\n", id)return}fmt.Printf("Worker %d: Received %d\n", id, value)}
}func main() {ch := make(chan int, 5)for i := 1; i <= 3; i++ {go worker(i, ch)}for i := 0; i < 10; i++ {ch <- ifmt.Printf("Sent %d\n", i)}close(ch)time.Sleep(time.Second) // 等待所有工作协程处理完
}
这个程序创建了一个缓冲通道,并启动了多个 goroutine 作为 worker 来处理通道中的数据。当数据全部发送完毕后,关闭通道并结束程序。
相关文章:
go语言中的通道(channel)详解
在 Go 语言中,通道(channel) 是一种用于在 goroutine(协程)之间传递数据的管道。通道具有类型安全性,即它只能传递一种指定类型的数据。通道是 Go 并发编程的重要特性,能够让多个 goroutine 之间…...
【JS】内置类型的相关问题
我是目录 引言内置类型undefined与nullnull和undefined的区别字符串转换为字符串数字0.1+0.2不等于0.3NaNBigInt大数相加问题原生函数(封箱与解封)判断类型的方法typeofinstanceofObject.prototype.toString.callconstructor类型转换toStringtoNumbertoBoolean显式强制类型转…...

Mac上无法访问usr/local的文件
sudo chmod 755 /usr/loca 最后用百度提供的方法解决了...
http 常见状态码
1xx 信息,表示临时响应并需要请求者继续执行操作 2xx 成功,操作被成功接收并处理 3xx 表示要完成请求,需要进一步操作。通常,这些状态码用来重定向 4xx 客户端错误,请求包含语法错误或无法完成请求 5xx 服务…...
代码训练营 day59|并查集
前言 这里记录一下陈菜菜的刷题记录,主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕,一年车企软件开发经验 代码能力:有待提高 常用语言:C 系列文章目录 第59天 :第十一章:图论part05 文章目录…...

Node.js——fs模块-路径补充说明
1、相对路径: ./座右铭.txt 当前目录下的座右铭.txt座右铭.txt 等效于上面的写法../座右铭.txt 当前目录的上一级目录中的座右铭.txt 2、绝对路径 D:/Program File Windows系统下的绝对路径/usr/bin Linux系统…...

华为ENSP--ISIS路由协议
项目背景 为了确保资源共享、办公自动化和节省人力成本,公司E申请两条专线将深圳总部和广州、北京两家分公司网络连接起来。公司原来运行OSFP路由协议,现打算迁移到IS-IS路由协议,张同学正在该公司实习,为了提高实际工作的准确性和…...
论软件可靠性设计及其应用
摘要 2023 年 3 月,我所在的公司承接了某智慧加油站平台的建设工作。该项目旨在帮助加油站提升运营效率、降低运营成本和提高销售额。我在该项目中担任系统架构设计师,负责整个项目的架构设计工作。 本文结合我在该项目中的实践,详细论述了…...

Android中桌面小部件framework层使用到的设计模式
在Android中,桌面小部件(App Widget)的Framework层采用了多种设计模式,以实现模块化、可维护性和高效的交互。 以下是Android桌面小部件Framework层中常用的设计模式及其具体应用: 1. 观察者模式(Observe…...

【JavaEE进阶】HTML
本节⽬标 认识 HTML 的基本结构, 学习常⽤的 HTML 标签. 一 HTML基础 1.什么是HTML HTML(Hyper Text Markup Language), 超⽂本标记语⾔. 超⽂本: ⽐⽂本要强⼤. 通过链接和交互式⽅式来组织和呈现信息的⽂本形式. 不仅仅有⽂本, 还可能包含图⽚, ⾳频, 或者⾃已经审阅过它…...

ElasticSearch 添加IK分词器
ElasticSearch 添加IK分词器 前言一、IK分词器的算法二、Ik分词器的下载安装(Winows 版本)三、Ik分词器的下载安装(Linux 版本)四、验证测试(postman工具)测试 ik_smart 分词算法测试 ik_max_word 分词算法…...

可视化建模与UML《顺序图实验报告》
旷野的规则是永不回头。 一、实验目的: 1、熟悉顺序图的构件事物。 2、熟悉发送者与接受者的关系 3、熟练掌握描绘顺序图 4、加深对顺序图的理解和应用能力 二、实验环境: window7 | 10 | 11 EA15 三、实验内容: 据如下描述绘制顺序图&…...

Mac的极速文件搜索工具,高效管理文件
Mac的资源管理可以说是许多转Mac的朋友用不明白的一点了,访达怎么用,文件怎么找,为什么找不到,非常的头大 All作为Mac上的极速文件搜索管理工具,有效的为文件查找困难的用户解决难题 基于极速搜索引擎,快…...
公开仓库改私有再配置公钥后Git拉取仍需要输入用户名的问题
问题描述:git拉取私有仓库需要输入用户名和密码 我之前写了一个脚本用来定时自动拉取远程仓库更新本地仓库,后来将这个远程仓库改成私有后执行脚本就会需要输入用户名和密码。 [rootLH2020 ~]# ./sync_repo.sh 正在从远程仓库拉取最新更改… Username f…...

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置
工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置...-CSDN博客 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明 工作流初始错误 泛微提交流程提示_泛微OA 工作流WebService接口使用说明-CSDN博客 工作…...

window下安装rust 及 vscode配置
安装 安装mingw64 (c语言环境 选择posix-ucrt) ucrt:通用c运行时库配置mingw64/bin的路径到环境变量中在cmd窗口中输入命令 "gcc -v" 4. 下载Rust安装程序 安装 Rust - Rust 程序设计语言 5. 配置rustup和cargo目录 (cargo是包管…...
【数据结构】【线性表】单链表1—概念即创建(附C语言源码)
单链表的定义, 链表用链式存储的方式实现线性表,链表中每个结点元素中需要指向下一个结点的指针(有时候也要指向上一个结点的指针),链表中的每个结点指针只指向下一结点的被叫为单链表。 单链表的创建和初始化 先定…...

centos7的maven配置
首先进入conf配置文件夹下的setting.xml 要改两个地方 第一:设置镜像源 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>https://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>c…...
day57 图论章节刷题Part08(拓扑排序、dijkstra(朴素版))
拓扑排序-117. 软件构建 思路:拓扑排序是经典的图论问题。给出一个有向图,把有向图转成线性的排序就叫拓扑排序,拓扑排序也要检测有向图是否有环,即存在循环依赖的情况,因为这种情况是不能做线性排序的,所…...

【Steam登录】protobuf协议逆向
https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1 搜索 input_protobuf_encoded定位 input_protobuf_encoded的值就是 o s r.SerializeBody() o i.iI(s) 精准定位 打上条件断点:t ‘Authentication.GetPasswordRSAPublicKey…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...

剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建
华为云FlexusDeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色,华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型,能助力我们轻松驾驭 DeepSeek-V3/R1,本文中将分享如何…...