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

Go 语言的 channel

channel

Go 语言的 channel(通道)是 Go 并发编程中的核心概念之一,
它提供了一种线程安全的方式来在 goroutine 之间传递数据。

通过 channel,可以在不同的 goroutine 之间进行通信和同步。

通道是 Go 的并发模型中的核心工具之一,它使用了“通信顺序进程”(CSP,Communicating Sequential Processes)模型,
允许不同的任务(goroutine)以同步和异步的方式交换数据。

  1. channel 的基本特性

类型安全:channel 的类型在定义时是固定的,一个 channel 只能传输一种类型的数据。

同步通信:如果一个 goroutine 发送数据到 channel,而另一个 goroutine 没有准备好接收数据,发送会被阻塞。
同样,接收者会在没有数据时被阻塞。

无缓冲(默认)和 有缓冲:channel 可以是无缓冲的(默认)或有缓冲的。
无缓冲 channel 会强制发送和接收操作是同步的;有缓冲 channel 则允许异步传输数据,直到缓冲区满。

  1. 创建和使用 Channel

3.1 创建 Channel

Go 使用 make 函数来创建 channel,并通过指定类型来确定 channel 传递的数据类型。你可以选择是否指定缓冲区大小。

无缓冲 Channel(默认)

ch := make(chan int) // 创建一个传输整数的无缓冲 channel

有缓冲 Channel(指定缓冲区大小)

ch := make(chan int, 2) // 创建一个传输整数的缓冲区大小为 2 的 channel

有缓冲的 channel 可以存储一定数量的数据,当缓冲区满时,发送操作将被阻塞,直到有数据被接收。

3.2 发送和接收数据

发送数据:
使用 <- 操作符将数据发送到 channel 中。

ch <- 42 // 将值 42 发送到 channel ch 中

接收数据:
使用 <- 操作符从 channel 中接收数据。

value := <-ch // 从 channel ch 中接收数据,并赋值给变量 value
  1. 通道的阻塞行为

channel 的操作是阻塞的,意思是:

如果发送者没有接收者准备好,发送操作会被阻塞。

如果接收者没有数据,接收操作会被阻塞。

func main() {ch := make(chan int) // 创建无缓冲 channelgo func() {fmt.Println("Sending data to channel...")ch <- 42 // 阻塞,直到主 goroutine 准备好接收fmt.Println("Data sent!")}()fmt.Println("Receiving data from channel...")value := <-ch // 接收数据,阻塞直到数据可用fmt.Println("Received:", value)
}
Receiving data from channel...
Sending data to channel...
Data sent!
Received: 42
  1. 使用有缓冲的 Channel

有缓冲的 channel 允许异步发送数据。

发送者可以在缓冲区满之前将数据发送到 channel,而接收者则可以在稍后的时候接收数据。

package mainimport "fmt"func main() {ch := make(chan int, 2) // 创建一个缓冲区大小为 2 的 channelch <- 1 // 发送数据到 channel,非阻塞ch <- 2 // 发送数据到 channel,非阻塞fmt.Println("Received:", <-ch) // 接收数据fmt.Println("Received:", <-ch) // 接收数据
}
Received: 1
Received: 2
  1. close 和 range 用法

关闭 Channel:当你不再需要发送数据时,可以通过 close 函数关闭 channel,
通知接收方没有更多的数据会被发送。关闭后的 channel 可以继续接收数据,但无法再发送数据。

package mainimport "fmt"func main() {ch := make(chan int, 3) // 创建有缓冲的 channelgo func() {for i := 1; i <= 3; i++ {ch <- i}close(ch) // 发送完所有数据后关闭 channel}()for value := range ch { // 遍历 channel,直到它关闭fmt.Println(value)}
}
  1. select 用法

select 语句类似于 switch,但它用于选择多个 channel 操作中的一个。它可以同时等待多个 channel 的事件发生,并在其中一个 channel 可用时执行相应的操作。

package mainimport "fmt"func main() {ch1 := make(chan string)ch2 := make(chan string)go func() {ch1 <- "Hello from channel 1"}()go func() {ch2 <- "Hello from channel 2"}()select {case msg1 := <-ch1:fmt.Println("Received:", msg1)case msg2 := <-ch2:fmt.Println("Received:", msg2)}
}
select 会等待 ch1 或 ch2 中的任何一个 channel 的消息。当其中一个 channel 收到消息时,相应的 case 就会被执行。
http://www.dtcms.com/a/441881.html

相关文章:

  • python包管理器——uv
  • 【LeetCode】92. 反转链表 II
  • LeetCode:90.最长有效括号
  • AI 重塑行业格局:从金融风控到智能制造的深度实践
  • 网站开发公共文件太仓营销型网站建设
  • MSM多标量乘法:策略及挑战
  • 做58一样的网站网站如何在国外推广
  • Vue渲染—深入VNode(h函数、JSX、render函数)
  • GPT_Data_Processing_Tutorial
  • 华为AC+AP无线网络组网与配置指南
  • 交互动效设计
  • 电子商务网站建设与管理相关文献邢台路桥建设总公司没有网站吗
  • Leetcode 3700. Number of ZigZag Arrays II
  • Turbopack介绍(由Vercel开发的基于Rust的高性能前端构建工具,用于挑战传统构建工具Webpack、vite地位)Next.js推荐构建工具
  • 网站自适应 如何做ui设计可以从事什么工作
  • 【学习记录】宝塔面板 + Docker 快速部署 RustDesk 自建远程控制服务器
  • 【3DGS复现】Autodl服务器复现3DGS《简单快速》《一次成功》《新手练习复现必备》
  • ollama的下载以及Spring AI Alibaba的ChatModel和ChatClient的流式输出和在idea的实现
  • 自己搭建服务器 发布网站 域名如何申请深圳专业做网站专业
  • 【pytest】fixture 内省(Introspection)测试上下文
  • 【开题答辩实录分享】以《基于python的奶茶店分布数据分析与可视化》为例进行答辩实录分享
  • 嵌入式硬件——基于IMX6ULL的I2C实现
  • 【ROS2学习笔记】分布式通信
  • 唐尧文化 网站建设工作总结邢台手机网站制作
  • 心脏病监测数据可视化分析
  • 【机器人】WMNav 将VLM融入世界模型 | 零样本目标导航 | IROS‘25
  • 第七课(零基础友好版)|机器学习像养宠物:数据—训练—测试(五年级·自学)
  • 无法解析插件 org.apache.maven.plugins:maven-site-plugin:3.12.1
  • 即墨网站建设哪里有安卓app怎么开发
  • 告别性能焦虑:Python 性能革命实践指南