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语言中协程(线程)与传…...
Android Studio:键值对存储sharedPreferences
一、了解 SharedPreferences SharedPreferences是Android的一个轻量级存储工具,它采用的存储结构是Key-Value的键值对方式,类似于Java的Properties,二者都是把Key-Value的键值对保存在配置文件中。不同的是,Properties的文件内容形…...
网络安全-攻击路径
以下是互联网场景下常见的攻击路径分类及详细说明,以分层结构呈现: 一、网络层攻击路径 DDoS攻击 原理:通过僵尸网络发起海量请求淹没目标服务器示例:SYN Flood攻击、HTTP洪泛攻击影响:服务不可用,带宽资源…...
记录阿里云CDN配置
网站接入CDN全流程,共4步!-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点: 1. 域名和泛域名区别 2.开启https,要用nginx的证书,和项…...
国自然专项项目申请:AI赋能的急性心肌梗死预警研究|基金申请·25-02-14
小罗碎碎念 急性心肌梗死严重威胁生命健康,因其起病隐匿、发病机制复杂,早期预警困难。现在,转机来了!国自然“AI赋能的急性心肌梗死预警研究”专项项目2025年度指南重磅发布。 该项目致力于攻克难题,通过多学科交叉…...
【鸿蒙开发】第二十八章 应用状态的讲解、状态持久化、网络管理、应用数据持久化、文件上传下载
目录 1 应用状态 1.1 LocalStorage:页面级UI状态存储 1.1.1 两个页面共享一个对象 1.1.2 页面间共享 1.1.3 应用逻辑中使用 1.2 AppStorage:应用全局的UI状态存储 1.2.1 概述 1.2.2 基本用法 1.2.3 经常使用的方法 1.3 PersistentStorage&#x…...
学习threejs,使用HemisphereLight半球光
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.HemisphereLight 二、…...
天童美语:观察你的生活
在孩子的认知里,世界宛如一片充满神秘色彩的未知之境,有着无尽的奥秘等待他们去探索。家长们,引导孩子用心观察世界,领略其中的美妙,这对孩子的成长进程有着极为关键的作用。贵阳天童教育相信:观察生活&…...
数仓:核心概念,数仓系统(ETL,数仓分层,数仓建模),数仓建模方法(星型模型,雪花模型,星座模型)和步骤
数仓建模的核心概念 事实表(Fact Table): 存储业务过程的度量值(如销售额、订单数量等)。 通常包含外键,用于关联维度表。 维度表(Dimension Table): 存储描述性信息&…...
python 基础知识100问
目录 1 Python中函数的输入参数类型: 2 python 第一个方法参数 selt cls 3 类和面向对象 4 Python 中__init__.py 作用 5 python 元类与装饰器 元类与装饰器https://blog.csdn.net/qq_52213943/article/details/145175689?spm1001.2014.3001.5506 6 设…...
Linux入侵检查流程
1. 初步信息收集 1.1 系统信息 • 目的:了解当前系统的基本情况,包括操作系统版本、内核版本等。 • 命令: # 查看操作系统发行版信息 cat /etc/os-release # 查看内核版本 uname -r 1.2 网络信息 • 目的:查看网络连接状态、…...
pg_sql关于时间的函数
1、时间戳和日期之间的相互转换 时间戳转日期(时间戳为数值类型,若为字符型需进行转换) # 保留到秒:2025-10-02 04:46:40 (字符型转换数值型) select to_timestamp(1759351600::bigint)# 保留到日&#x…...
如何使用 DeepSeek R1 构建开源 ChatGPT Operator 替代方案
开源大型语言模型(LLMs)的兴起使得创建 AI 驱动的工具比以往任何时候都更容易,这些工具可以与 OpenAI 的 ChatGPT Operator 等专有解决方案相媲美。在这些开源模型中,DeepSeek R1 以其强大的推理能力、自由的可访问性和适应性而脱…...
【教程】MySQL数据库学习笔记(七)——多表操作(持续更新)
写在前面: 如果文章对你有帮助,记得点赞关注加收藏一波,利于以后需要的时候复习,多谢支持! 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…...
Word 公式转 CSDN 插件 发布
经过几个月的苦修,这款插件终于面世了。 从Word复制公式到CSDN粘贴,总是出现公式中的文字被单独提出来,而公式作为一个图片被粘贴的情况。公式多了的时候还会导致CSDN禁止进一步的上传公式。 经过对CSDN公式的研究,发现在粘贴公…...
【设计模式】 建造者模式和原型模式
建造者模式(Builder Pattern) 概述 建造者模式是一种创建型设计模式,它允许逐步构建复杂对象。通过将构造过程与表示分离,使得同样的构建过程可以创建不同的表示。这种模式非常适合用于创建那些具有很多属性的对象,尤…...
win7误删注册表文件夹导致exe无法执行
今天在装某个软件的时候报错 “不是有效的Win32应用程序”,找一篇文章于是按文章删除了注册表上的好多文件,之后就发现所有的exe文件都打不开了,更糟糕的是中间还弹出来一个“是否将IE设置为所有程度的默认执行程序”,没思考就点击…...
【ESP32接入国产大模型之Deepseek】
【ESP32接入国产大模型之Deepseek】 1. Deepseek大模型1.1 了解Deepseek api1.2 Http接口鉴权1.3. 接口参数说明1.3.1 请求体(request)参数1.3.2 模型推理 2. 先决条件2.1 环境配置2.2 所需零件 3. 核心代码3.1 源码分享3.2 源码解析3.3 连续对话修改后的代码代码说明示例输出注…...
C语言蓝桥杯1003: [编程入门]密码破译
要将"China"译成密码,译码规律是:用原来字母后面的第4个字母代替原来的字母. 例如,字母"A"后面第4个字母是"E"."E"代替"A"。因此,"China"应译…...
New Game--(单调队列)
I - New Game 有一种新的游戏,Monocarp 想要玩。这个游戏使用一副包含 n 张牌的牌堆,其中第 i 张牌上写有一个整数 a_i。 在游戏开始时,Monocarp 可以在第一轮选择牌堆中的任意一张牌。在接下来的每一轮中,Monocarp 可以选择一张…...
什么是偏光环形光源
偏光环形光源是一种特殊的光源,常用于机器视觉、光学检测和工业自动化等领域。它结合了环形光源和偏光技术,能够有效减少反射、增强对比度,特别适用于检测高反光或表面复杂的物体。 主要特点: 环形设计:光线均匀照射物…...
SolidWorks速成教程P3-3【零件 | 第三节】——草图绘制面实线与构造线的区别
经过了前面的特征学习后,是不是感觉对 SolidWorks越来越熟悉了?不过发现, SolidWorks速成这套教程,对于一些基础问题,还是需要解释得更详细一些,所以在这节再补充一下草图绘制面&实线与构造线的区别。 目录 1.草图绘制面 2.实线与构造线的区别 1.草图绘制面 之前…...
win10中mstsc远程Centos-Stream 9图形化界面
文章目录 1 前置状态2 安装配置XRDP3 关闭SELinux3.1 查看selinux状态3.2 关闭selinux 4 启动XRDP5 Win10远程连接测试 1 前置状态 已安装CentOS9桌面版;Windows10。 2 安装配置XRDP sudo yum install epel-release sudo yum install xrdp sudo yum install tige…...
中国AI“拥抱开源”给世界的启示——Anko
事实证明,中国AI企业“拥抱开源”,不仅为自身发展开拓了新路径,也带动AI企业跨国合作的需求,并推动全球AI生态向“开源普惠”转型。Anko通过免费开放部分模型功能,将AI时代的数字红利公平地派发到每一位网民手中&#…...
DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件
1 DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强,如果不能在企业的自有业务上产生助益,那基本也是一无是处。将企业的自有业务上传到线上训练,那是脑子进水的做法ÿ…...
Jenkins 配置 Git Parameter 四
Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件,请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…...
力扣-二叉树-110 平衡二叉树
思路 用后序分别求出每一个节点的左子树和右子树高度,然后判断是否符合定义,再判断两个子树是否符合定义 代码 class Solution { public:int getDepth(TreeNode* node){if(node nullptr) return 0;return max( getDepth(node->left), getDepth(no…...
Linux 查看磁盘中的大文件
在 Linux 系统中,你可以使用以下方法来查看磁盘中的大文件信息: 1. 使用 find 命令 find 命令可以递归查找指定目录下的大文件。 find /path/to/directory -type f -size 100M -exec ls -lh {} \;/path/to/directory:要查找的目录路径&…...
网络工程师 (38)流量和差错控制
一、流量控制 流量控制是一种协调发送站和接收站工作步调的技术。它的主要目的是防止发送端发送数据过快,导致接收端缓冲区溢出,从而造成数据丢失。流量控制机制通过调整发送速率来匹配接收端的处理能力。 基本原理 发送站每发出一帧数据,就进…...
vue3多个页面/组件,复用同一段render页面根据接口返回的数据动态渲染逻辑,使用setup+组合式API
组件reusableComponent是可供多个组件复用的 getData请求接口,render渲染数据 <template><render /> </template> <script setup> import operationService from "/views/operation/component/operationService.vue";const prop…...
