当前位置: 首页 > news >正文

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 语言中&#xff0c;通道&#xff08;channel&#xff09; 是一种用于在 goroutine&#xff08;协程&#xff09;之间传递数据的管道。通道具有类型安全性&#xff0c;即它只能传递一种指定类型的数据。通道是 Go 并发编程的重要特性&#xff0c;能够让多个 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 信息&#xff0c;表示临时响应并需要请求者继续执行操作 2xx 成功&#xff0c;操作被成功接收并处理 3xx 表示要完成请求&#xff0c;需要进一步操作。通常&#xff0c;这些状态码用来重定向 4xx 客户端错误&#xff0c;请求包含语法错误或无法完成请求 5xx 服务…...

代码训练营 day59|并查集

前言 这里记录一下陈菜菜的刷题记录&#xff0c;主要应对25秋招、春招 个人背景 211CS本CUHK计算机相关硕&#xff0c;一年车企软件开发经验 代码能力&#xff1a;有待提高 常用语言&#xff1a;C 系列文章目录 第59天 &#xff1a;第十一章&#xff1a;图论part05 文章目录…...

Node.js——fs模块-路径补充说明

1、相对路径&#xff1a; ./座右铭.txt 当前目录下的座右铭.txt座右铭.txt 等效于上面的写法../座右铭.txt 当前目录的上一级目录中的座右铭.txt 2、绝对路径 D&#xff1a;/Program File Windows系统下的绝对路径/usr/bin Linux系统…...

华为ENSP--ISIS路由协议

项目背景 为了确保资源共享、办公自动化和节省人力成本&#xff0c;公司E申请两条专线将深圳总部和广州、北京两家分公司网络连接起来。公司原来运行OSFP路由协议&#xff0c;现打算迁移到IS-IS路由协议&#xff0c;张同学正在该公司实习&#xff0c;为了提高实际工作的准确性和…...

论软件可靠性设计及其应用

摘要 2023 年 3 月&#xff0c;我所在的公司承接了某智慧加油站平台的建设工作。该项目旨在帮助加油站提升运营效率、降低运营成本和提高销售额。我在该项目中担任系统架构设计师&#xff0c;负责整个项目的架构设计工作。 本文结合我在该项目中的实践&#xff0c;详细论述了…...

Android中桌面小部件framework层使用到的设计模式

在Android中&#xff0c;桌面小部件&#xff08;App Widget&#xff09;的Framework层采用了多种设计模式&#xff0c;以实现模块化、可维护性和高效的交互。 以下是Android桌面小部件Framework层中常用的设计模式及其具体应用&#xff1a; 1. 观察者模式&#xff08;Observe…...

【JavaEE进阶】HTML

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

ElasticSearch 添加IK分词器

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

可视化建模与UML《顺序图实验报告》

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

Mac的极速文件搜索工具,高效管理文件

Mac的资源管理可以说是许多转Mac的朋友用不明白的一点了&#xff0c;访达怎么用&#xff0c;文件怎么找&#xff0c;为什么找不到&#xff0c;非常的头大 All作为Mac上的极速文件搜索管理工具&#xff0c;有效的为文件查找困难的用户解决难题 基于极速搜索引擎&#xff0c;快…...

公开仓库改私有再配置公钥后Git拉取仍需要输入用户名的问题

问题描述&#xff1a;git拉取私有仓库需要输入用户名和密码 我之前写了一个脚本用来定时自动拉取远程仓库更新本地仓库&#xff0c;后来将这个远程仓库改成私有后执行脚本就会需要输入用户名和密码。 [rootLH2020 ~]# ./sync_repo.sh 正在从远程仓库拉取最新更改… Username f…...

工作流初始错误 泛微提交流程提示_泛微协同办公平台E-cology8.0版本后台维护手册(11)–系统参数设置

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

window下安装rust 及 vscode配置

安装 安装mingw64 &#xff08;c语言环境 选择posix-ucrt&#xff09; ucrt:通用c运行时库配置mingw64/bin的路径到环境变量中在cmd窗口中输入命令 "gcc -v" 4. 下载Rust安装程序 安装 Rust - Rust 程序设计语言 5. 配置rustup和cargo目录 &#xff08;cargo是包管…...

【数据结构】【线性表】单链表1—概念即创建(附C语言源码)

单链表的定义&#xff0c; 链表用链式存储的方式实现线性表&#xff0c;链表中每个结点元素中需要指向下一个结点的指针&#xff08;有时候也要指向上一个结点的指针&#xff09;&#xff0c;链表中的每个结点指针只指向下一结点的被叫为单链表。 单链表的创建和初始化 先定…...

centos7的maven配置

首先进入conf配置文件夹下的setting.xml 要改两个地方 第一&#xff1a;设置镜像源 <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>https://maven.aliyun.com/nexus/content/groups/public/</url> <mirrorOf>c…...

day57 图论章节刷题Part08(拓扑排序、dijkstra(朴素版))

拓扑排序-117. 软件构建 思路&#xff1a;拓扑排序是经典的图论问题。给出一个有向图&#xff0c;把有向图转成线性的排序就叫拓扑排序&#xff0c;拓扑排序也要检测有向图是否有环&#xff0c;即存在循环依赖的情况&#xff0c;因为这种情况是不能做线性排序的&#xff0c;所…...

【Steam登录】protobuf协议逆向

https://api.steampowered.com/IAuthenticationService/GetPasswordRSAPublicKey/v1 搜索 input_protobuf_encoded定位 input_protobuf_encoded的值就是 o s r.SerializeBody() o i.iI(s) 精准定位 打上条件断点&#xff1a;t ‘Authentication.GetPasswordRSAPublicKey…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Fabric V2.5 通用溯源系统——增加图片上传与下载功能

fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...