Go语言并发(一)——goroutine与Waitgroup

协程

前言

在很多语言中都会提到并发的概念, 例如python, Java,C++等等,一般来说 都会
使用多线程或多进程来 实现并发调度,但是多线程/进程 一般会耗费大量内存, 而在go
语言中我们可以使用协程来达到并发调度的目的,

协程的简介

协程是轻量级的线程(或者说是用户态的线程),与常用的线程不同的是,它本身的调度不由操作系统
来完成,而是由go语言本身所带的调度器来完成,进而减少了上下文切换的开销,这也是go语言性能提升的原因。

协程的简单使用

与其他语言不同的是,go语言中协程的实现非常简单,只需要关键字go就可以实现一个协程,如下:

package mainimport "fmt"func synchello() {fmt.Println("hello world")
}func main() {go synchello()
}

在这里我们就利用了go关键字实现了一个简单的协程,但是上面的代码没有任何的输出,
因为虽然我们利用go关键字已经创建出了子协程,但是由于我们的父协程(main函数)已经
结束了,所以子协程也就无法执行了,所以如果我们想让子协程执行,那么我们就需要让父
协程在子协程结束之前先不要结束,如下:

package mainimport ("fmt""time"
)func synchello() {fmt.Println("hello world")
}func main() {go synchello()time.Sleep(10 * time.Second)
}

这样我们就可以看到子协程的输出了,但是这种方法并不是最佳的比如下面这个代码:

package mainimport ("fmt""time"
)func synchello() {fmt.Println("hello world")
}func main() {for i := 0; i <= 20; i++ {go func() {fmt.Println(i)}()}time.Sleep(30 * time.Second)
}

输出结果为:

10
15
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21
21

可以看到,我们并没有按照我们期望的顺序输出,事实上在并发编程上,我们使用Sleep
函数并不是一种高明的手段,Go中给我们提供了很多并发控制的手段,例如:

  • channel: 管道,用于协程之间的通信
  • Context: 上下文,用于协程之间的通信
  • WaitGroup: 信号量
  • Mutex: 互斥锁
  • RWMutex: 读写互斥锁
    我们可以利用它们来实现我们所想要的并发控制

WaitGrouop(信号量)

WaitGroup的介绍及使用

什么是Waitgroup

WaitGroup是Go语言中一个并发控制工具,它由sync包提供,WairGroup即等待执行,
我们可以利用它轻易的实现等待一组协程的效果

WaitGroup的结构

Waitgroup向外暴露了三个方法:

  • Add:该方法指明了需要我们等待线程的数量
func (wg *WaitGroup) Add(delta int)
  • Done:该方法表示一个线程已经执行完毕,当所有的线程都执行完毕之后,Wait方法
    才会返回
func (wg *WaitGroup) Done()
  • Wait:该方法表示等待所有的线程执行完毕
func (wg *WaitGroup) Wait()

WaitGroup的使用

WaitGroup的使用非常简单,它的内部实现主要是基于计数器+信号量,程序刚开始时
调用Add来初始化计数,每当一个协程执行完毕后调用Done,这时计数就-1,直到减为
0,在这期间Wait会一直阻塞主协程直到全部计数都减为0,此时主协程才会被唤醒
我们来看一个简单示例:

package mainimport ("fmt""sync"
)func main() {var wait sync.WaitGroupwait.Add(1)go func() {defer wait.Done()fmt.Println(1)}()wait.Wait()fmt.Println(2)
}

输出结果为:

1
2

我们还可以来看一下接下来的这个样例:

package mainimport ("fmt""sync"
)func main() {var mainwait sync.WaitGroupvar wait sync.WaitGroupmainwait.Add(10)for i := 0; i < 10; i++ {defer wait.Done()defer mainwait.Done()func(i int) {fmt.Println(i)}(i)wait.Wait()   //等循环执行完毕}mainwait.Wait()
}

执行结果为:

0
1
2
3
4
5
6
7
8
9

WaitGroup通常会用于动态调整协程的数量,比如我们在事先就已经知道了协程的数量
又或者是我们在运行过程中需要去动态的调整,而我们在使用Waitgroup时也不应该
复制它的值,如果我们想将其作为函数参数进行传递的时候,需要传递指针而不是复制它的值
值。倘若使用复制的值,计数完全无法作用到真正的WaitGroup上,这可能会导致主协程一直
阻塞等待,程序将无法正常运行。
示例:

package mainimport ("fmt""sync"
)func main() {var wait sync.WaitGroupwait.Add(1)hello(&wait)wait.Wait()fmt.Println("end")
}func hello(wait *sync.WaitGroup) {fmt.Println("hello")wait.Done()
}

当计数变为负数,或者计数数量大于子协程数量时,将会引发panic.

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

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

相关文章

高级优化理论与方法(七)

高级优化理论与方法&#xff08;七&#xff09; Solving Linear EquationsCase 2TheoremKaczmarzs AlgorithmTheoremExample PseudoinverseDefinitionSpecial Case 1Special Case 2 Properties of PseudoinverseLemma 1: Unique pseudoinverseLemma 2: Full Rank Factorization…

Pytorch实用教程:Pytorch中model.eval()和torch.no_grad()的作用及用法

文章目录 1. model.eval()为什么需要 .eval() 方法&#xff1f;使用 .eval() 方法示例 注意事项 2. torch.no_grad()为什么需要 torch.no_grad()&#xff1f;使用 torch.no_grad()示例场景注意事项 1. model.eval() model.eval() 在 PyTorch 中是一个重要的方法&#xff0c;用…

MySQL8.3.0 主从复制方案(master/slave)

一 、什么是MySQL主从 MySQL主从&#xff08;Master-Slave&#xff09;复制是一种数据复制机制&#xff0c;用于将一个MySQL数据库服务器&#xff08;主服务器&#xff09;的数据复制到其他一个或多个MySQL数据库服务器&#xff08;从服务器&#xff09;。这种复制机制可以提供…

如何让阿里云AI001号员工帮我写代码(含IDEA插件使用)

国内首个AI程序员入职阿里云&#xff1a;专属工号AI001&#xff0c;KPI是一人写完公司20%代码。 不管是真是假&#xff0c;AI 程序员发展的趋势是无法改变的&#xff0c;小米汽车发布会上&#xff0c;雷军说到小米汽车工厂的自动化率达到90%以上&#xff0c;有些车间甚至100%的…

手术麻醉系统源码 医疗信息管理系统源码C#.net6.0+ vs2022,vscode+BS网页版 手麻系统源码

手术麻醉系统源码 医疗信息管理系统源码C#.net6.0 vs2022,vscodeB/S网页版 手麻系统源码 手术麻醉管理系统是应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进行全程跟踪与信息管理&#xff0c;自动集成病人HIS、LIS、RIS、PACS信息&…

jdk8新特性 方法引用

简介 lambda表达式是用来简化匿名内部类的方法引用 使用来简化 lambda表达式的 方法引用的标志 两个冒号 静态方法 静态方法 class CompareByAge {public static int compare(Student o1, Student o2) {return o1.getAge() - o2.getAge();} }静态方法引用 Arrays.sort(students…

表格比对作业指导书 使用access对excel表格数据进行比对

初级代码游戏的专栏介绍与文章目录-CSDN博客 &#xff08;注&#xff1a;这是以前给秘书写的作业指导书&#xff0c;用来处理两个表格中哪些人存在、哪些人不存在。看起来当时使用的access版本是2016。access是微软office套件中的一个软件&#xff0c;存在于家庭版&#xff0c…

探秘Vue异步组件,深入解析

基本用法​ 在大型项目中&#xff0c;我们可能需要拆分应用为更小的块&#xff0c;并仅在需要时再从服务器加载相关组件。Vue 提供了defineAsyncComponent方法来实现此功能&#xff1a; import { defineAsyncComponent } from vueconst AsyncComp defineAsyncComponent(() >…

​SCP收容物041~050​

注 &#xff1a;此文接SCP收容物031~040,本文只供开玩笑 ,与steve_gqq_MC合作。 --------------------------------------------------------------------------------------------------------------------------------- 目录 scp-041 scp-042 scp-043 scp-044 scp-045…

二维相位解包理论算法和软件【全文翻译- 噪声滤波(3.53.6)】

3.5 噪音过滤 在本节中,我们将简要讨论相位数据的滤波问题。除了提高信噪比之外,噪声滤波还有助于减少残差的数量,从而大大简化相位解包过程。不过,我们必须注意到一个重要的问题。正如我们在第 1 章中指出的,相位本身并不是信号。它只是信号的一种属性。因此,应该过滤的…

JSON字符串中获取一个特定字段的值

JSON字符串中获取一个特定字段的值 一、方式一&#xff0c;引用gson工具二、方式二&#xff0c;使用jackson三、方式三&#xff0c;使用jackson转换Object四、方式四&#xff0c;使用hutool&#xff0c;获取报文数组数据 一、方式一&#xff0c;引用gson工具 测试报文&#xf…

表单流程管理系统:推进数字化转型理想助手

在数字化转型新时代&#xff0c;谁拥有理想的软件平台助手&#xff0c;谁就能在流程化管理新进程中迈出坚实的步伐。面对激烈的市场竞争&#xff0c;低代码技术平台及表单流程管理系统正在广阔的市场环境中越扎越稳&#xff0c;成为助力企业数字化转型升级的重要利器设备。想要…

使用PyCharm安装并运行python程序(小白专属教程,建议收藏)

本文将介绍如何使用pycharm安装python环境并运行第一个python程序&#xff0c;适合刚接触python的童鞋参考。 Python的安装 python是一门跨平台的语言&#xff0c;如Windows、Linux、MacOS等平台都能完美兼容&#xff0c;以下只对Windows平台安装做详细介绍。 &#xff11;.…

开创加密资产新纪元:深度解析ERC-314协议

随着加密资产市场的不断发展和区块链技术的日益成熟&#xff0c;新的协议和标准不断涌现&#xff0c;其中包括了ERC-314协议。本文将深入分析ERC-314协议的特点、功能以及对加密资产市场可能产生的影响。 1. ERC-314协议简介 ERC-314协议是一项建立在以太坊区块链上的新提案&a…

鲁大师2024年Q1季度电动车报告:新老品牌角逐电自市场,九号699分夺魁

鲁大师2024年Q1季报正式发布&#xff0c;本次季报包含电动车智能排行&#xff0c;测试的车型为市面上主流品牌的主流车型&#xff0c;共计12款&#xff0c;全部按照评测维度更广、更专业的鲁大师电动车智慧评测2.0进行评分&#xff0c;测试的成绩均来自于鲁大师智慧硬件实验室。…

新规解读 | 被网信办豁免数据出境申报义务的企业,还需要做什么?

为了促进数据依法有序自由流动&#xff0c;激发数据要素价值&#xff0c;扩大高水平对外开放&#xff0c;《促进和规范数据跨境流动规定》&#xff08;以下简称《规定》&#xff09;对数据出境安全评估、个人信息出境标准合同、个人信息保护认证等数据出境制度作出优化调整。 …

QAnything-1.3.0,支持纯python笔记本运行,支持混合检索

QAnything 1.3.0 更新了&#xff0c;这次带来两个主要功能&#xff0c;一个是纯python的安装&#xff0c;另一个是混合检索。更多详情见&#xff1a; https://github.com/netease-youdao/QAnything/releases 纯python安装 我们刚发布qanything开源的时候&#xff0c;希望用户…

冯喜运:4.8晚间黄金原油走势分析及操作建议

黄金走势分析&#xff1a;      金价在亚洲大国市场开盘后突然飙升约30美元至历史新高&#xff0c;触发了交易员的积极反应。这一行情主要是因为亚洲大国央行持续增加黄金储备的预期所致&#xff0c;而且市场对全球央行今年可能的大规模黄金购买提前建立了多头头寸。数据显…

数据转换 | Matlab基于GADF格拉姆角差场一维数据转二维图像方法

目录 效果分析基本介绍程序设计参考资料获取方式 效果分析 基本介绍 GADF&#xff08;Gramian Angular Difference Field&#xff09;是一种将时间序列数据转换为二维图像的方法之一。它可以用于提取时间序列数据的特征&#xff0c;并可应用于各种领域&#xff0c;如时间序列分…

【深入理解Java IO流0x05】Java缓冲流:为提高IO效率而生

1. 引言 我们都知道&#xff0c;内存与硬盘的交互是比较耗时的&#xff0c;因此适当得减少IO的操作次数&#xff0c;能提升整体的效率。 Java 的缓冲流是对字节流和字符流的一种封装&#xff08;装饰器模式&#xff0c;关于IO流中的一些设计模式&#xff0c;后续会再出博客来讲…