Go语言协程Goroutine高级用法(一)
什么协程
在Go语言中,协程就是一种轻量的线程,是并发编程的单元,由Go来管理,所以在GO层面的协程会更加的轻量、高效、开销更小,并且更容易实现并发编程。
轻量级线程
- Go语言中协程(线程)与传统系统层面的线程相比,实在是太轻量了,能小到2kb
- 由于协程的轻量特性,可以更高效地利用系统资源。相较于传统的线程,协程的创建和销毁的开销更小,使得程序更具有扩展性和性能优势。
Go自身管理
- 在 Go 中,这些工作由运行时系统自动完成。这样我们就可以更专注于业务逻辑,而不必过多关心底层线程管理的细节。
并发的基本单元
- 协程是并发编程的基本单元,可以同时执行多个协程,而它们之间的调度和切换由运行时系统负责。
- 在程序中更容易实现高效的并发,处理多个任务而无需显式地创建和管理线程。
- 使用协程,我们可以轻松地实现并发任务,例如同时处理多个网络请求、执行后台任务等。由于协程的轻量特性,可以创建数千甚至数百万个协程而不会造成系统负担。
使用通道通信
- 协程之间可以通过通道进行通信,这是一种在协程之间安全地传递数据和同步操作的机制。通道是一种强大的工具,用于协程之间的协作和数据传递。
协程的基本操作
创建协程
- 语法: `go 函数(函数列表)`
package main import ( "fmt" "time") func Hello() { fmt.Println("hello world")
} func main() { go Hello() fmt.Println("hello main") time.Sleep(10 * time.Second)
}
协程与主线程是并发执行的。
协程间通行
- 主要通过
channel来实现的
package main import ( "fmt"
) func sendMessage(ch chan string, msg string) { ch <- msg
} func main() { messagechan := make(chan string) go sendMessage(messagechan, "Hello World") msg := <-messagechan fmt.Println(msg)
}
协程间的同步
- 使用sync包来实现的
- waitgroup 是用来计数信号量的
package main import ( "fmt" "sync") func worker(id int, wg *sync.WaitGroup) { defer wg.Done() fmt.Printf("worker %d starting\n", id) fmt.Printf("worker %d done\n", id)
} func main() { var wg sync.WaitGroup for i := 1; i <= 10; i++ { wg.Add(1) go worker(i, &wg) } wg.Wait() fmt.Printf("all workers done\n")
}
waitgroup确保主线程等待所有协程完成
协程的错误处理
- 使用
select语句和通道可以实现协程的错误处理
package main import ( "fmt" "time") func dosomething(ch chan string) { time.Sleep(2 * time.Second) ch <- "hello world"
} func main() { ch := make(chan string) go dosomething(ch) select { case msg := <-ch: fmt.Println(msg) case <-time.After(1 * time.Second): fmt.Println("timeout") }
}
select语句允许在多个通道操作中选择一个可用的操作,可以用来处理协程的超时等情况。
协程的高级操作
协程池
- 协程池是一组预先创建的协程,用于执行并发任务,可以避免频繁创建和销毁协程的开销。
- 使用缓冲通道来实现协程池
package main import ( "fmt" "sync") func worker(id int, jobs <-chan int, results chan<- int) { for j := range jobs { fmt.Println("worker", id, "started job", j) results <- j * 2 }
} func main() { const numJobs = 5 const numWorkers = 3 jobs := make(chan int, numJobs) results := make(chan int, numJobs) var wg sync.WaitGroup for i := 1; i <= numWorkers; i++ { wg.Add(1) go func(i int) { defer wg.Done() worker(i, jobs, results) }(i) } for j := 1; j <= 5; j++ { jobs <- j } close(jobs) go func() { wg.Wait() close(results) }() for result := range results { fmt.Println("result", result) }
}
三个协程形成了协程池,从任务通道
jobs中获取任务,处理后将结果发送到结果通道results
超时控制
package main import ( "fmt" "time") func dosomething(ch chan string) { time.Sleep(2 * time.Second) ch <- "hello world"
} func main() { ch := make(chan string) go dosomething(ch) select { case msg := <-ch: fmt.Println(msg) case <-time.After(1 * time.Second): fmt.Println("timeout") }
}
time.After创建一个计时器,如果在指定时间内没有从通道ch中接收到结果,就会触发超时。
协程的取消
- 使用
context包提供的上下文(Context)来实现协程的取消。
package main import ( "context" "fmt" "time") func doSomething(ctx context.Context, ch chan string) { select { case <-ctx.Done(): ch <- "task completed successfully" case <-time.After(1 * time.Second): ch <- "task timed out" }
} func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() ch := make(chan string) go doSomething(ctx, ch) time.Sleep(2 * time.Second) cancel() result := <-ch fmt.Println(result)
}
通过调用
cancel函数取消协程的执行。
相关文章:
Go语言协程Goroutine高级用法(一)
什么协程 在Go语言中,协程就是一种轻量的线程,是并发编程的单元,由Go来管理,所以在GO层面的协程会更加的轻量、高效、开销更小,并且更容易实现并发编程。 轻量级线程 Go语言中协程(线程)与传…...
DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
1 DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强,如果不能在企业的自有业务上产生助益,那基本也是一无是处。将企业的自有业务上传到线上训练,那是脑子进水的做法ÿ…...
【鸿蒙HarmonyOS Next实战开发】lottie动画库
简介 lottie是一个适用于OpenHarmony和HarmonyOS的动画库,它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画,并在移动设备上进行本地渲染。 下载安裝 ohpm install ohos/lottieOpenHarmony ohpm 环境配置等更多内容,…...
PAT乙级真题 — 1084 外观数列(java)
外观数列是指具有以下特点的整数序列: d, d1, d111, d113, d11231, d112213111, ...它从不等于 1 的数字 d 开始,序列的第 n1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d,所以就是 d1;第 2 项是 1 个 d(对…...
从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地
导读:日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案,替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度,规模达到…...
STM32——HAL库开发笔记19(串口中断接收实验)(参考来源:b站铁头山羊)
本实验,我们以中断的方式使得串口发送数据控制LED的闪烁速度,发送1,慢闪;发送2,速度正常;发送3,快闪。 一、电路连接图 二、实现思路&CubeMx配置 1、实现控制LED的闪烁速度 uint32_t bli…...
清影2.0(AI视频生成)技术浅析(二):自然语言处理
清影2.0(AI视频生成)中的自然语言处理(NLP)技术是其核心组件之一,负责将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指导后续的视频生成过程。 一、基本原理 1. 目标 清影2.0的NLP技术旨在将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指…...
Unity序列化多态数组
文档 Json序列化 脚本序列化 问题 Unity序列化数组时,只能存储基类内容,子类内容缺少。 Unity版本 2019.4.40 原因:Unity序列化不支持多态 测试类 将testarray类序列化时,多态列表personlist只转换了基类数据,子类…...
Spring Framework 中文官方文档
spring的部分中文文档。给总结在下面了: 看英文的大佬可以绕路了哈哈哈 一、 历史、设计理念、反馈、入门。 二、 IoC 容器、事件、资源、i18n、验证、数据绑定、类型转换、SpEL、AOP 三、 模拟对象、TestContext 框架、Spring MVC 测试、WebTestClient。 四、 事…...
力扣-二叉树-257 二叉树的所有路径
思路 除去根节点,每一层添加->val,然后使用前序遍历的顺序 代码 class Solution { public:vector<string> res;void getTreePaths(string s, TreeNode* root){s "->";s to_string(root->val);if(root->left nullptr &…...
如何调整 Nginx工作进程数以提升性能
🏡作者主页:点击! Nginx-从零开始的服务器之旅专栏:点击! 🐧Linux高级管理防护和群集专栏:点击! ⏰️创作时间:2025年2月15日14点20分 Nginx 的工作进程数࿰…...
FreeRTOS-rust食用指南
Rust 环境安装 rustup 是 Rust 的安装程序,也是它的版本管理程序,Linux 命令行下使用如下方式安装 # 安装 rustup curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh #更新 rustup rustup update# 版本检查 rustc -V cargo -VFreeRTOS-rust…...
如何使用智能化RFID管控系统,对涉密物品进行安全有效的管理?
载体主要包括纸质文件、笔记本电脑、优盘、光盘、移动硬盘、打印机、复印机、录音设备等,载体(特别是涉密载体)是各保密、机要单位保证涉密信息安全、防止涉密信息泄露的重要信息载体。载体管控系统主要采用RFID射频识别及物联网技术…...
0基础学LabVIEW
对于零基础的朋友来说,学习LabVIEW需要一个科学的学习路径和方法。通过观看优质的B站教程打好基础,再结合实际项目进行实践操作,能够快速提升LabVIEW的应用能力。以下是从入门到进阶的学习建议。 一、利用B站入门教程打基础 筛选优质教程…...
Go语言精进之路读书笔记(第二部分-项目结构、代码风格与标识符命名)
说明:《Go语言精进之路》第一部分-熟知Go语言的一切,不在博客中做读书笔记了,大家可以自己读一读,每个人心里都会有自己对Go语言的认识和理解。 直接从第二部分-项目接口、代码风格与标识符命名开始 第二章目录如下 第5条 使用…...
Windows server 2016 无法部署docker问题
根据流程winserver16安装docker ee,发现服务器管理器的添加角色和功能-功能中没有 container 根据流程winserver16安装docker desktop,发现安装 hyper-v 报错 原因: 本人测试用windows server 2016使用vmware搭建,而vmware本身可…...
智能AI之隐私安全,尤其是医疗
前言 智能AI能更好的服务我们的生活,各行各业都将会有她的影子。我们在依赖她的情况下,我们的隐私安全吗? 前两天分享了用她分析CT拍片、还有一份血检报告单,回复的确实比有些医生都说的专业全面。以至于我都有冲动依赖她开…...
【hot100】054螺旋矩阵
一、思路 这个题目主要有两个问题,一是什么时候切换方向,二是如何切换方向 问题一:此步移动完后,判断下一个元素,如果大于等于边界值(从0开始)或者小于边界值时或者访问数组为真时 问题二&am…...
【Java学习】类和对象
目录 一、选择取块解 二、类变量 三、似复刻变量 四、类变量的指向对象 五、变量的解引用访问 1.new 类变量(参) 2.this(参) 3.类变量/似复刻变量. 六、代码块 七、复制变量的赋值顺序 八、访问限定符 1.private 2.default 九、导类 一、选择取块解 解引用都有可以…...
TestHubo基础教程-创建项目
TestHubo是一款国产开源一站式测试工具,涵盖功能测试、接口测试、性能测试,以及 Web 和 App 测试,可以满足不同类型项目的测试需求。本文将介绍如何快速创建第一个项目,以快速入门上手。 1、创建项目 在 TestHubo 中,…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
Rust 异步编程
Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...
