Go 语言中的 `select` 语句详解

select 是 Go 语言中处理通道(Channel)操作的一个强大控制结构,它允许 goroutine 同时等待多个通道操作。下面我将全面详细地解释 select 语句的各个方面。

基本语法

select 语句的基本语法如下:

select {
case <-ch1:// 如果从 ch1 成功接收数据,则执行此分支
case x := <-ch2:// 如果从 ch2 成功接收数据,则执行此分支,并将值赋给 x
case ch3 <- y:// 如果成功向 ch3 发送数据 y,则执行此分支
default:// 如果以上 case 都不满足,则执行此分支
}

工作原理

  1. 多路复用select 会阻塞,直到其中一个 case 可以执行
  2. 随机选择:当多个 case 同时就绪时,Go 会随机选择一个执行
  3. 非阻塞:当有 default 分支时,select 不会阻塞

详细特性

1. 基本通道操作

ch1 := make(chan string)
ch2 := make(chan string)go func() { ch1 <- "hello" }()
go func() { ch2 <- "world" }()select {
case msg1 := <-ch1:fmt.Println("received", msg1)
case msg2 := <-ch2:fmt.Println("received", msg2)
}

2. 超时控制

select 常与 time.After 结合实现超时:

select {
case res := <-someChan:fmt.Println(res)
case <-time.After(time.Second * 1):fmt.Println("timeout after 1 second")
}

3. 非阻塞操作

使用 default 实现非阻塞的通道操作:

select {
case msg := <-ch:fmt.Println("received", msg)
default:fmt.Println("no message received")
}

4. 永久阻塞

空的 select 会永久阻塞:

select {}
// 这常用于阻止 main 函数退出

5. 循环 select

通常与 for 循环结合使用:

for {select {case x := <-ch1:fmt.Println(x)case y := <-ch2:fmt.Println(y)case <-quit:return}
}

高级用法

1. 优先级处理

如果需要优先处理某个通道,可以这样实现:

for {select {case highPrio := <-highPriorityChan:// 处理高优先级default:select {case highPrio := <-highPriorityChan:// 处理高优先级case lowPrio := <-lowPriorityChan:// 处理低优先级}}
}

2. 动态 case

使用反射可以实现动态的 select case:

cases := []reflect.SelectCase{{Dir:  reflect.SelectRecv,Chan: reflect.ValueOf(ch1),},{Dir:  reflect.SelectRecv,Chan: reflect.ValueOf(ch2),},
}chosen, value, _ := reflect.Select(cases)
fmt.Printf("Chosen %d, value %v", chosen, value)

3. 退出模式

done := make(chan struct{})go func() {defer close(done)// 工作代码
}()select {
case <-done:// 正常完成
case <-time.After(timeout):// 超时处理
}

注意事项

  1. 死锁风险:如果所有 case 都阻塞且没有 default,会导致死锁
  2. 性能考虑:频繁的 select 可能影响性能,在高性能场景需谨慎使用
  3. 通道关闭:从已关闭的通道接收会立即返回零值,可能导致意外行为
  4. 随机选择:多个 case 就绪时的随机选择可能导致优先级问题

实际应用示例

1. 服务多个客户端

func serve(ch1, ch2 <-chan Request, quit <-chan bool) {for {select {case req := <-ch1:handleRequest(req)case req := <-ch2:handleRequest(req)case <-quit:return}}
}

2. 竞速请求

func race(url1, url2 string) (string, error) {ch := make(chan string, 2)go func() { ch <- request(url1) }()go func() { ch <- request(url2) }()select {case resp := <-ch:return resp, nilcase <-time.After(time.Second * 5):return "", fmt.Errorf("timeout")}
}

3. 工作池模式

func worker(id int, jobs <-chan int, results chan<- int) {for j := range jobs {select {case <-time.After(time.Second): // 模拟超时fmt.Printf("worker %d timeout\n", id)default:fmt.Printf("worker %d processing job %d\n", id, j)results <- j * 2}}
}

select 语句是 Go 并发编程的核心工具之一,熟练掌握它对于编写高效、健壮的并发程序至关重要。

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

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

相关文章

AI如何重塑CC防护行业?五大变革与实战策略解析

一、CC防护行业的技术痛点与AI的破局方向 CC攻击&#xff08;Challenge Collapsar&#xff09;作为一种以高频合法请求消耗服务器资源的DDoS攻击手段&#xff0c;传统防护技术面临三大核心挑战&#xff1a; 规则依赖性强&#xff1a;基于IP封禁或请求频率的静态规则易被绕过&a…

GPT-4o最新图像生成完全指南:10大应用场景与提示词模板

引言 OpenAI于近期推出的全新GPT-4o图像生成功能&#xff0c;代表了AI图像创作领域的重大突破。作为一个原生多模态系统&#xff0c;GPT-4o将文本理解和图像生成无缝整合&#xff0c;为创作者、教育工作者和专业人士提供了前所未有的视觉创作灵活性。本文将分享10个GPT-4o图像…

Linux驱动开发2 - 内核定时器驱动

背景 所有驱动开发都是基于全志T507&#xff08;Android 10&#xff09;进行开发&#xff0c;用于记录驱动开发过程。 简介 定时器是比较常用的一个功能&#xff0c;用来执行周期性任务。一般不太精确的定时可以用系统提供的延时函数进行。如果需要进行较为精确的延时&#…

Dify 使用 excel 或者 csv 文件创建知识库

Dify 使用 excel 或者 csv 文件创建知识库 1. 创建知识库2. 创建聊天助手3. 其他 1. 创建知识库 创建知识库&#xff0c;导入excel/csv文件&#xff0c; 文件内容&#xff0c; 单击 “预览块”&#xff0c;可以确认会生成多个键值对的块&#xff0c; 配置 Embedding 模型和检索…

23种设计模式-行为型模式之迭代器模式(Java版本)

Java 迭代器模式&#xff08;Iterator Pattern&#xff09;详解 &#x1f9e0; 什么是迭代器模式&#xff1f; 迭代器模式是一种行为型设计模式&#xff0c;它提供一种方法顺序访问一个聚合对象中的各个元素&#xff0c;而不暴露该对象的内部表示。 &#x1f3af; 使用场景 …

使用nodeJs的express+axios+cors做代理

使用nodeJs的expressaxioscors做代理 前端在请求后端时通常会遇到跨域cors问题&#xff0c;如果只在本地开发可以通过webpack或vite的proxy设置。但如果需要在线上或者其他地方绕过跨域&#xff0c;可以使用代理的方法。 1. 创建文件夹 并创建以下文件 package.json {"…

T检验、F检验及样本容量计算学习总结

目录 〇、碎语一、假设检验1.1 两种错误1.2 z检验和t检验1.3 t检验1.3.1 单样本t检验1.3.2 配对样本t检验1.3.3 独立样本t检验1.4 方差齐性检验1.4 卡方检验二、样本容量的计算2.1 AB测试主要的两种应用场景2.2 绝对量的计算公式2.3 率的计算公式参考资料〇、碎语 听到最多的检…

tensorflow使用详解

一、TensorFlow基础环境搭建 安装与验证 # 安装CPU版本 pip install tensorflow# 安装GPU版本&#xff08;需CUDA 11.x和cuDNN 8.x&#xff09; pip install tensorflow-gpu# 验证安装 python -c "import tensorflow as tf; print(tf.__version__)"核心概念 Tensor…

Redis的阻塞

Redis的阻塞 Redis的阻塞问题主要分为内在原因和外在原因两大类&#xff0c;以下从这两个维度展开分析&#xff1a; 一、内在原因 1. 不合理使用API或数据结构 Redis 慢查询 Redis 慢查询的界定 定义&#xff1a;Redis 慢查询指命令执行时间超过预设阈值&#xff08;默认 10m…

SLAM学习系列——ORB-SLAM3安装(Ubuntu20-ROS/Noetic)

ORB-SLAM3学习&#xff08;Ubuntu20-ROS&#xff09; 0 主要参考文献1 ORB-SLAM3安装环境配置1.0 前言1.0.0 关于ORB-SLAM3安装版本选择1.0.1 本文配置操作汇总(快速配置)1.0.1.1 ORB_SLAM3环境配置&#xff1a;1.0.1.2 ORB_SLAM3安装1.0.1.3 ORB_SLAM的ROS接口 1.1 C&#xff…

【应用密码学】实验二 分组密码(2)

一、实验要求与目的 1&#xff09; 学习AES密码算法原理 2&#xff09; 学习AES密码算法编程实现 二、实验内容与步骤记录&#xff08;只记录关键步骤与结果&#xff0c;可截图&#xff0c;但注意排版与图片大小&#xff09; 字符串加解密 运行python程序&#xff0c;输入…

区块链基石解码:分布式账本的运行奥秘与技术架构

区块链技术的革命性源于其核心组件——分布式账本&#xff08;Distributed Ledger&#xff09;。这一技术通过去中心化、透明性和不可篡改性&#xff0c;重塑了传统数据存储与交易验证的方式。本文将从分布式账本的核心概念、实现原理、应用场景及挑战等方面展开&#xff0c;揭…

AUTOSAR_RS_ClassicPlatformDebugTraceProfile

AUTOSAR经典平台调试、跟踪与分析支持 AUTOSAR组件调试、跟踪与分析功能详解 目录 简介ARTI核心扩展 核心特定ARTI扩展结构核心参数定义 操作系统和任务扩展 OS特定ARTI扩展任务特定ARTI扩展软件组件特定扩展 总体架构 组件结构接口定义 错误处理 默认错误跟踪器(DET) 总结 1.…

SpringBoot配置RestTemplate并理解单例模式详解

在日常开发中&#xff0c;RestTemplate 是一个非常常用的工具&#xff0c;用来发起HTTP请求。今天我们通过一个小例子&#xff0c;不仅学习如何在SpringBoot中配置RestTemplate&#xff0c;还会深入理解单例模式在Spring中的实际应用。 1. 示例代码 我们首先来看一个基础的配置…

DPIN在AI+DePIN孟买峰会阐述全球GPU生态系统的战略愿景

DPIN基金会在3月29日于印度孟买举行的AIDePIN峰会上展示了其愿景和未来5年的具体发展计划&#xff0c;旨在塑造去中心化算力的未来。本次活动汇集了DPIN、QPIN、社区成员和Web3行业资深顾问&#xff0c;深入探讨DPIN构建全球领先的去中心化GPU算力网络的战略&#xff0c;该网络…

央视两次采访报道爱藏评级,聚焦生肖钞市场升温,评级币成交易安全“定心丸”

CCTV央视财经频道《经济信息联播》《第一时间》两档节目分别对生肖贺岁钞进行了5分钟20秒的专题报道。长期以来&#xff0c;我国一直保持着发行生肖纪念钞和纪念币的传统&#xff0c;生肖纪念钞和纪念币在收藏市场保持着较高的热度。特别是2024年初&#xff0c;央行发行了首张贺…

【计算机哲学故事1-2】输入输出(I/O):你吸收什么,便成为什么

“我最近&#xff0c;是不是废了……”她瘫在沙发上&#xff0c;手机扣在胸口&#xff0c;盯着天花板自言自语。 我坐在一旁&#xff0c;随手翻着桌上的杂志&#xff0c;没接话&#xff0c;等着她把情绪发泄完。 果然&#xff0c;几秒后&#xff0c;她重重地叹了口气&#xf…

封装el-autocomplete,接口调用

组件 <template><el-autocompletev-model"selectedValue":fetch-suggestions"fetchSuggestions":placeholder"placeholder"select"handleSelect"clearablev-bind"$attrs"/> </template><script lang&…

GPUStack昇腾Atlas300I duo部署模型DeepSeek-R1【GPUStack实战篇2】

2025年4月25日GPUStack发布了v0.6版本&#xff0c;为昇腾芯片910B&#xff08;1-4&#xff09;和310P3内置了MinIE推理&#xff0c;新增了310P芯片的支持&#xff0c;很感兴趣&#xff0c;所以我马上来捣鼓玩玩看哈 官方文档&#xff1a;https://docs.gpustack.ai/latest/insta…

Linux进程详细解析

1.操作系统 概念 任何计算机系统都包含⼀个基本的程序集合&#xff0c;称为操作系统(OS)。笼统的理解&#xff0c;操作系统包括&#xff1a; • 内核&#xff08;进程管理&#xff0c;内存管理&#xff0c;文件管理&#xff0c;驱动管理&#xff09; • 其他程序&#xff08…