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

Go语言协程Goroutine高级用法(一)

什么协程

在Go语言中,协程就是一种轻量的线程,是并发编程的单元,由Go来管理,所以在GO层面的协程会更加的轻量、高效、开销更小,并且更容易实现并发编程。

轻量级线程

  1. Go语言中协程(线程)与传统系统层面的线程相比,实在是太轻量了,能小到2kb
  2. 由于协程的轻量特性,可以更高效地利用系统资源。相较于传统的线程,协程的创建和销毁的开销更小,使得程序更具有扩展性和性能优势。

Go自身管理

  1. 在 Go 中,这些工作由运行时系统自动完成。这样我们就可以更专注于业务逻辑,而不必过多关心底层线程管理的细节。

并发的基本单元

  1. 协程是并发编程的基本单元,可以同时执行多个协程,而它们之间的调度和切换由运行时系统负责。
  2. 在程序中更容易实现高效的并发,处理多个任务而无需显式地创建和管理线程。
  3. 使用协程,我们可以轻松地实现并发任务,例如同时处理多个网络请求、执行后台任务等。由于协程的轻量特性,可以创建数千甚至数百万个协程而不会造成系统负担。

使用通道通信

  1. 协程之间可以通过通道进行通信,这是一种在协程之间安全地传递数据和同步操作的机制。通道是一种强大的工具,用于协程之间的协作和数据传递。

协程的基本操作

创建协程

- 语法: `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语言中&#xff0c;协程就是一种轻量的线程&#xff0c;是并发编程的单元&#xff0c;由Go来管理&#xff0c;所以在GO层面的协程会更加的轻量、高效、开销更小&#xff0c;并且更容易实现并发编程。 轻量级线程 Go语言中协程&#xff08;线程&#xff09;与传…...

DeepSeek处理自有业务的案例:让AI给你写一份小众编辑器(EverEdit)的语法着色文件

1 DeepSeek处理自有业务的案例&#xff1a;让AI给你写一份小众编辑器(EverEdit)的语法着色文件 1.1 背景 AI能力再强&#xff0c;如果不能在企业的自有业务上产生助益&#xff0c;那基本也是一无是处。将企业的自有业务上传到线上训练&#xff0c;那是脑子进水的做法&#xff…...

【鸿蒙HarmonyOS Next实战开发】lottie动画库

简介 lottie是一个适用于OpenHarmony和HarmonyOS的动画库&#xff0c;它可以解析Adobe After Effects软件通过Bodymovin插件导出的json格式的动画&#xff0c;并在移动设备上进行本地渲染。 下载安裝 ohpm install ohos/lottieOpenHarmony ohpm 环境配置等更多内容&#xff0c…...

PAT乙级真题 — 1084 外观数列(java)

外观数列是指具有以下特点的整数序列&#xff1a; d, d1, d111, d113, d11231, d112213111, ...它从不等于 1 的数字 d 开始&#xff0c;序列的第 n1 项是对第 n 项的描述。比如第 2 项表示第 1 项有 1 个 d&#xff0c;所以就是 d1&#xff1b;第 2 项是 1 个 d&#xff08;对…...

从 ClickHouse 到 Apache Doris:在网易云音乐日增万亿日志数据场景下的落地

导读&#xff1a;日志数据已成为企业洞察系统状态、监控网络安全及分析业务动态的宝贵资源。网易云音乐引入 Apache Doris 作为日志库新方案&#xff0c;替换了 ClickHouse。解决了 ClickHouse 运维复杂、不支持倒排索引的问题。目前已经稳定运行 3 个季度&#xff0c;规模达到…...

STM32——HAL库开发笔记19(串口中断接收实验)(参考来源:b站铁头山羊)

本实验&#xff0c;我们以中断的方式使得串口发送数据控制LED的闪烁速度&#xff0c;发送1&#xff0c;慢闪&#xff1b;发送2&#xff0c;速度正常&#xff1b;发送3&#xff0c;快闪。 一、电路连接图 二、实现思路&CubeMx配置 1、实现控制LED的闪烁速度 uint32_t bli…...

清影2.0(AI视频生成)技术浅析(二):自然语言处理

清影2.0(AI视频生成)中的自然语言处理(NLP)技术是其核心组件之一,负责将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指导后续的视频生成过程。 一、基本原理 1. 目标 清影2.0的NLP技术旨在将用户输入的自然语言文本转化为机器可以理解的语义表示,从而指…...

Unity序列化多态数组

文档 Json序列化 脚本序列化 问题 Unity序列化数组时&#xff0c;只能存储基类内容&#xff0c;子类内容缺少。 Unity版本 2019.4.40 原因&#xff1a;Unity序列化不支持多态 测试类 将testarray类序列化时&#xff0c;多态列表personlist只转换了基类数据&#xff0c;子类…...

Spring Framework 中文官方文档

spring的部分中文文档。给总结在下面了&#xff1a; 看英文的大佬可以绕路了哈哈哈 一、 历史、设计理念、反馈、入门。 二、 IoC 容器、事件、资源、i18n、验证、数据绑定、类型转换、SpEL、AOP 三、 模拟对象、TestContext 框架、Spring MVC 测试、WebTestClient。 四、 事…...

力扣-二叉树-257 二叉树的所有路径

思路 除去根节点&#xff0c;每一层添加->val&#xff0c;然后使用前序遍历的顺序 代码 class Solution { public:vector<string> res;void getTreePaths(string s, TreeNode* root){s "->";s to_string(root->val);if(root->left nullptr &…...

如何调整 Nginx工作进程数以提升性能

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年2月15日14点20分 Nginx 的工作进程数&#xff0…...

FreeRTOS-rust食用指南

Rust 环境安装 rustup 是 Rust 的安装程序&#xff0c;也是它的版本管理程序&#xff0c;Linux 命令行下使用如下方式安装 # 安装 rustup curl --proto https --tlsv1.2 https://sh.rustup.rs -sSf | sh #更新 rustup rustup update# 版本检查 rustc -V cargo -VFreeRTOS-rust…...

如何使用智能化RFID管控系统,对涉密物品进行安全有效的管理?

载体主要包括纸质文件、笔记本电脑、优盘、光盘、移动硬盘、打印机、复印机、录音设备等&#xff0c;载体&#xff08;特别是涉密载体&#xff09;是各保密、机要单位保证涉密信息安全、防止涉密信息泄露的重要信息载体。载体管控系统主要采用RFID射频识别及物联网技术&#xf…...

0基础学LabVIEW

对于零基础的朋友来说&#xff0c;学习LabVIEW需要一个科学的学习路径和方法。通过观看优质的B站教程打好基础&#xff0c;再结合实际项目进行实践操作&#xff0c;能够快速提升LabVIEW的应用能力。以下是从入门到进阶的学习建议。 ​ 一、利用B站入门教程打基础 筛选优质教程…...

Go语言精进之路读书笔记(第二部分-项目结构、代码风格与标识符命名)

说明&#xff1a;《Go语言精进之路》第一部分-熟知Go语言的一切&#xff0c;不在博客中做读书笔记了&#xff0c;大家可以自己读一读&#xff0c;每个人心里都会有自己对Go语言的认识和理解。 直接从第二部分-项目接口、代码风格与标识符命名开始 第二章目录如下 第5条 使用…...

Windows server 2016 无法部署docker问题

根据流程winserver16安装docker ee&#xff0c;发现服务器管理器的添加角色和功能-功能中没有 container 根据流程winserver16安装docker desktop&#xff0c;发现安装 hyper-v 报错 原因&#xff1a; 本人测试用windows server 2016使用vmware搭建&#xff0c;而vmware本身可…...

智能AI之隐私安全,尤其是医疗

前言 智能AI能更好的服务我们的生活&#xff0c;各行各业都将会有她的影子。我们在依赖她的情况下&#xff0c;我们的隐私安全吗&#xff1f; 前两天分享了用她分析CT拍片、还有一份血检报告单&#xff0c;回复的确实比有些医生都说的专业全面。以至于我都有冲动依赖她开…...

【hot100】054螺旋矩阵

一、思路 这个题目主要有两个问题&#xff0c;一是什么时候切换方向&#xff0c;二是如何切换方向 问题一&#xff1a;此步移动完后&#xff0c;判断下一个元素&#xff0c;如果大于等于边界值&#xff08;从0开始&#xff09;或者小于边界值时或者访问数组为真时 问题二&am…...

【Java学习】类和对象

目录 一、选择取块解 二、类变量 三、似复刻变量 四、类变量的指向对象 五、变量的解引用访问 1.new 类变量(参) 2.this(参) 3.类变量/似复刻变量. 六、代码块 七、复制变量的赋值顺序 八、访问限定符 1.private 2.default 九、导类 一、选择取块解 解引用都有可以…...

TestHubo基础教程-创建项目

TestHubo是一款国产开源一站式测试工具&#xff0c;涵盖功能测试、接口测试、性能测试&#xff0c;以及 Web 和 App 测试&#xff0c;可以满足不同类型项目的测试需求。本文将介绍如何快速创建第一个项目&#xff0c;以快速入门上手。 1、创建项目 在 TestHubo 中&#xff0c;…...

<6>-MySQL表的增删查改

目录 一&#xff0c;create&#xff08;创建表&#xff09; 二&#xff0c;retrieve&#xff08;查询表&#xff09; 1&#xff0c;select列 2&#xff0c;where条件 三&#xff0c;update&#xff08;更新表&#xff09; 四&#xff0c;delete&#xff08;删除表&#xf…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展&#xff0c;AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术&#xff0c;在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...