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

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;与传…...

Android Studio:键值对存储sharedPreferences

一、了解 SharedPreferences SharedPreferences是Android的一个轻量级存储工具&#xff0c;它采用的存储结构是Key-Value的键值对方式&#xff0c;类似于Java的Properties&#xff0c;二者都是把Key-Value的键值对保存在配置文件中。不同的是&#xff0c;Properties的文件内容形…...

网络安全-攻击路径

以下是互联网场景下常见的攻击路径分类及详细说明&#xff0c;以分层结构呈现&#xff1a; 一、网络层攻击路径 DDoS攻击 原理&#xff1a;通过僵尸网络发起海量请求淹没目标服务器示例&#xff1a;SYN Flood攻击、HTTP洪泛攻击影响&#xff1a;服务不可用&#xff0c;带宽资源…...

记录阿里云CDN配置

网站接入CDN全流程&#xff0c;共4步&#xff01;-阿里云开发者社区 1、开通阿里云CDN服务 2、添加加速域名 3、验证域名归属权 4、域名添加CDN生成的CNAME解析 按照官网描述增加。细节点&#xff1a; 1. 域名和泛域名区别 2.开启https,要用nginx的证书&#xff0c;和项…...

国自然专项项目申请:AI赋能的急性心肌梗死预警研究|基金申请·25-02-14

小罗碎碎念 急性心肌梗死严重威胁生命健康&#xff0c;因其起病隐匿、发病机制复杂&#xff0c;早期预警困难。现在&#xff0c;转机来了&#xff01;国自然“AI赋能的急性心肌梗死预警研究”专项项目2025年度指南重磅发布。 该项目致力于攻克难题&#xff0c;通过多学科交叉…...

【鸿蒙开发】第二十八章 应用状态的讲解、状态持久化、网络管理、应用数据持久化、文件上传下载

目录 1 应用状态 1.1 LocalStorage&#xff1a;页面级UI状态存储 1.1.1 两个页面共享一个对象 1.1.2 页面间共享 1.1.3 应用逻辑中使用 1.2 AppStorage&#xff1a;应用全局的UI状态存储 1.2.1 概述 1.2.2 基本用法 1.2.3 经常使用的方法 1.3 PersistentStorage&#x…...

学习threejs,使用HemisphereLight半球光

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.HemisphereLight 二、…...

天童美语:观察你的生活

在孩子的认知里&#xff0c;世界宛如一片充满神秘色彩的未知之境&#xff0c;有着无尽的奥秘等待他们去探索。家长们&#xff0c;引导孩子用心观察世界&#xff0c;领略其中的美妙&#xff0c;这对孩子的成长进程有着极为关键的作用。贵阳天童教育相信&#xff1a;观察生活&…...

数仓:核心概念,数仓系统(ETL,数仓分层,数仓建模),数仓建模方法(星型模型,雪花模型,星座模型)和步骤

数仓建模的核心概念 事实表&#xff08;Fact Table&#xff09;&#xff1a; 存储业务过程的度量值&#xff08;如销售额、订单数量等&#xff09;。 通常包含外键&#xff0c;用于关联维度表。 维度表&#xff08;Dimension Table&#xff09;&#xff1a; 存储描述性信息&…...

python 基础知识100问

目录 1 Python中函数的输入参数类型‌&#xff1a; 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 系统信息 • 目的&#xff1a;了解当前系统的基本情况&#xff0c;包括操作系统版本、内核版本等。 • 命令&#xff1a; # 查看操作系统发行版信息 cat /etc/os-release # 查看内核版本 uname -r 1.2 网络信息 • 目的&#xff1a;查看网络连接状态、…...

pg_sql关于时间的函数

1、时间戳和日期之间的相互转换 时间戳转日期&#xff08;时间戳为数值类型&#xff0c;若为字符型需进行转换&#xff09; # 保留到秒&#xff1a;2025-10-02 04:46:40 &#xff08;字符型转换数值型&#xff09; select to_timestamp(1759351600::bigint)# 保留到日&#x…...

如何使用 DeepSeek R1 构建开源 ChatGPT Operator 替代方案

开源大型语言模型&#xff08;LLMs&#xff09;的兴起使得创建 AI 驱动的工具比以往任何时候都更容易&#xff0c;这些工具可以与 OpenAI 的 ChatGPT Operator 等专有解决方案相媲美。在这些开源模型中&#xff0c;DeepSeek R1 以其强大的推理能力、自由的可访问性和适应性而脱…...

【教程】MySQL数据库学习笔记(七)——多表操作(持续更新)

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【MySQL数据库学习】系列文章 第一章 《认识与环境搭建》 第二章 《数据类型》 第三章 《数据定义语言DDL》 第四章 《数据操…...

Word 公式转 CSDN 插件 发布

经过几个月的苦修&#xff0c;这款插件终于面世了。 从Word复制公式到CSDN粘贴&#xff0c;总是出现公式中的文字被单独提出来&#xff0c;而公式作为一个图片被粘贴的情况。公式多了的时候还会导致CSDN禁止进一步的上传公式。 经过对CSDN公式的研究&#xff0c;发现在粘贴公…...

【设计模式】 建造者模式和原型模式

建造者模式&#xff08;Builder Pattern&#xff09; 概述 建造者模式是一种创建型设计模式&#xff0c;它允许逐步构建复杂对象。通过将构造过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。这种模式非常适合用于创建那些具有很多属性的对象&#xff0c;尤…...

win7误删注册表文件夹导致exe无法执行

今天在装某个软件的时候报错 “不是有效的Win32应用程序”&#xff0c;找一篇文章于是按文章删除了注册表上的好多文件&#xff0c;之后就发现所有的exe文件都打不开了&#xff0c;更糟糕的是中间还弹出来一个“是否将IE设置为所有程度的默认执行程序”&#xff0c;没思考就点击…...

【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"译成密码&#xff0c;译码规律是&#xff1a;用原来字母后面的第4个字母代替原来的字母&#xff0e; 例如&#xff0c;字母"A"后面第4个字母是"E"&#xff0e;"E"代替"A"。因此&#xff0c;"China"应译…...

New Game--(单调队列)

I - New Game 有一种新的游戏&#xff0c;Monocarp 想要玩。这个游戏使用一副包含 n 张牌的牌堆&#xff0c;其中第 i 张牌上写有一个整数 a_i。 在游戏开始时&#xff0c;Monocarp 可以在第一轮选择牌堆中的任意一张牌。在接下来的每一轮中&#xff0c;Monocarp 可以选择一张…...

什么是偏光环形光源

偏光环形光源是一种特殊的光源&#xff0c;常用于机器视觉、光学检测和工业自动化等领域。它结合了环形光源和偏光技术&#xff0c;能够有效减少反射、增强对比度&#xff0c;特别适用于检测高反光或表面复杂的物体。 主要特点&#xff1a; 环形设计&#xff1a;光线均匀照射物…...

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桌面版&#xff1b;Windows10。 2 安装配置XRDP sudo yum install epel-release sudo yum install xrdp sudo yum install tige…...

中国AI“拥抱开源”给世界的启示——Anko

事实证明&#xff0c;中国AI企业“拥抱开源”&#xff0c;不仅为自身发展开拓了新路径&#xff0c;也带动AI企业跨国合作的需求&#xff0c;并推动全球AI生态向“开源普惠”转型。Anko通过免费开放部分模型功能&#xff0c;将AI时代的数字红利公平地派发到每一位网民手中&#…...

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

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

Jenkins 配置 Git Parameter 四

Jenkins 配置 Git Parameter 四 一、开启 项目参数设置 勾选 This project is parameterised 二、添加 Git Parameter 如果此处不显示 Git Parameter 说明 Jenkins 还没有安装 Git Parameter plugin 插件&#xff0c;请先安装插件 Jenkins 安装插件 三、设置基本参数 点击…...

力扣-二叉树-110 平衡二叉树

思路 用后序分别求出每一个节点的左子树和右子树高度&#xff0c;然后判断是否符合定义&#xff0c;再判断两个子树是否符合定义 代码 class Solution { public:int getDepth(TreeNode* node){if(node nullptr) return 0;return max( getDepth(node->left), getDepth(no…...

Linux 查看磁盘中的大文件

在 Linux 系统中&#xff0c;你可以使用以下方法来查看磁盘中的大文件信息&#xff1a; 1. 使用 find 命令 find 命令可以递归查找指定目录下的大文件。 find /path/to/directory -type f -size 100M -exec ls -lh {} \;/path/to/directory&#xff1a;要查找的目录路径&…...

网络工程师 (38)流量和差错控制

一、流量控制 流量控制是一种协调发送站和接收站工作步调的技术。它的主要目的是防止发送端发送数据过快&#xff0c;导致接收端缓冲区溢出&#xff0c;从而造成数据丢失。流量控制机制通过调整发送速率来匹配接收端的处理能力。 基本原理 发送站每发出一帧数据&#xff0c;就进…...

vue3多个页面/组件,复用同一段render页面根据接口返回的数据动态渲染逻辑,使用setup+组合式API

组件reusableComponent是可供多个组件复用的 getData请求接口&#xff0c;render渲染数据 <template><render /> </template> <script setup> import operationService from "/views/operation/component/operationService.vue";const prop…...