Go——Goroutine介绍

一. 并发介绍

        进程和线程

  • 进程是程序在操作系统中一次执行过程,系统进程资源分配和调度的一个独立单位。
  • 线程是进程执行的实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。
  • 一个进程可以创建和撤销多个线程,同一个进程中的多个线程之间可以并发执行。

        并发和并行

  • 多线程程序在一个核CPU上运行,就是并发。
  • 多线程程序在多个核CPU上运行,就是并行。

        协程和线程

  • 协程:独立的栈空间,共享堆空间,调度由用户自己控制,本质有点类似于用户级线程,这些用户级线程的调度也是自己实现的。
  • 线程:一个线程上可以跑多个协程,协程是轻量级线程。

        goroutine只是由官方实现的超级“线程池”。

        每个实际4~5KB的栈内存占用和由于实现机制而大幅减少的创建和销毁开销是go高并发的根本原因。

        并发主要是由切换时间片来实现同时运行,并行则是直接利用多核实现多线程的运行,go可以设置使用核数,以发挥多核计算机的能力。

        goroutine奉行通过通信来共享内存,而不是共享内存来通信。

二. Goroutine

        2.1 介绍

        在java/c++中我们要实现一个并发编程,我们通常需要自己维护一个线程池,并且需要自己取包装一个有一个任务,同时需要自己去调度线程执行任务并维护上下文切换,这一切通常会耗费程序员大量心智。那么能不能有一种机制,程序员只需要定义很多任务,让系统去帮助我们把这些任务分配到CPU上实现并发执行呢?

        Go语言中的goroutine就是这样一种机制,goroutine的概念类似于线程,但goroutine是由Go的运行时(runtime)调度和管理的。Go程序会智能的将goroutine中的任务合理的分配给每一个CPU。Go语言之所以被称为现代化的编程语言,就是因为它在语言层面已经内置了调度核上下文切换的机制。

        在Go语言编程中,你不需要去自己写进程,线程,协程,你的技能包里只有一个技能-goroutine,当你需要让某个任务并发执行的时候,你只需要把这个任务包装成一个函数,开启一个goroutine去执行这个函数就可以了。

  • 使用goroutine

        Go语言中使用goroutine非常简单,只需要在调用函数的时候在前面加上go关键字,就可以为一个函数创建一个goroutine。

        一个goroutine必定对应一个函数,可以创建多个goroutine去执行相同函数。

        2.2 使用

  • 启动单个goroutine

        启动goroutine的方式非常简单,只需要在调用的函数(普通函数和匿名函数)前面加一个go关键字。

        使用协程:

  • 启动多个协程

        我们发现下面的打印不是按顺序打印的,这是因为协程是并发运行的,调度是随机的。

  • 注意:如果主协程退出了,其它子协程会不论在不在运行,会直接退出。

 2.3 goroutine与线程

  • 可增长的栈

        OS线程(操作系统的线程)一般由固定的栈内存(通常2MB),一个goroutine的栈在其生命周期开始只有很小的栈(典型情况下2KB),goroutine的栈不是固定的,它可以按需增大或缩小,goroutine的栈大小限制可以达到1GB,虽然极少会用到这么大。所以在Go语言中一次创建十万左右的goroutine也是可以的。

  • goroutine调度

        GPM是Go语言运行时(runtime)层面的实现,是go语言自己实现的一套调度系统。区别于操作系统调度OS线程。

  • G很好理解,就是个goroutine的,里面除了存放本goroutine信息外,还有与所在P的绑定等信息。
  • P管理着一组goroutine队列,P里面会存储当前goroutine运行的上下文环境(函数指针,堆栈信息及地址边界),P会对自己管理的goroutine队列做一些调度(比如把占用CPU时间较长的goroutine暂停,运行后续的goroutine等)当自己的队列消费完就去全局队列里面取,如果全局队列也消费完了会去其它P的队列里抢任务。
  • M(machine)是Go运行时(runtime)对操作系统内核线程的虚拟,M与内核线程一般是一一对应的关系,一个goroutine最终是要放到M上执行的。

        P与M一般也是一一对应。他们的关系:P管理着一组挂载在M上运行。当一个G长久阻塞在一个M上时,runtime会建立一个M,阻塞G所在的P会把其它的G挂载在新的M上,当旧的G阻塞完成或认为其已经死掉,回收旧的M。

        P的个数是通过runtime.GOMAXPROCS设定(最大256),Go1.5版本之后默认为物理线程数。在并发量大的时候会增加一些P和M,但不会太多,切换太频繁的话得不偿失。

        单从线程调度讲,Go语言相比起其它语言的优势在于OS线程是由OS内核调度的,goroutine则是由Go运行时(runtime)自己的调度器调度的,这个调度器使用一个称为m:n调度技术(复用/调度m个goroutine到n个OS线程)。其一大特点是goroutine的调度是在用户态下完成的,不涉及内核态与用户态之间的频繁切换,包括内存的分配与释放,都是在用户态维护着一个大的内存池,不直接调用系统的malloc函数(除非内存池需要改变),成本比调度OS线程低的多。另外一方面充分利用了多核的硬件资源,近似的把若干goroutine均分在物理线程上,再加上本身的goroutine的超轻量,以上种种保证了go调度方面的性能。

  • 总结

Go语言中的操作系统线程与goroutine之间的关系:

  • 一个操作系统线程对应用户态多个goroutine
  • go语言可以同时使用多个操作系统线程
  • goroutine和OS线程是多对多的关系,即m:n 

三.runtime包

  • runtime.Gosched()

        让出CPU时间片,重新等待安排任务。

package mainimport ("fmt""runtime"
)func main() {go func(s string) {for i := 0; i < 2; i++ {fmt.Println(s)}}("world")//主协程for i := 0; i < 2; i++ {runtime.Gosched() //切以下,再次分配任务fmt.Println("hello ")}
}
  • runtime.Goexit()

        退出当前协程。

  • runtime.GOMAXPROCS

        Go运行时的调度器使用GOMAXPROCS参数来确定需要使用多少个OS线程同时执行Go代码。默认值是机器上的CPU核心数。比如在一个8核心的机器上,调度器会把Go代码同时调度到8个OS线程上。(GOMAXPROCS是m:n调度中的n)

        Go语言可以通过runtime.GOMAXPROCS()函数设置当前程序并发时占用的CPU逻辑核心数。

        Go1.5版本之前,默认使用的是单核心执行。Go1.5版本之后,默认使用全部的CPU逻辑核心。

        我们可以通过将任务分配到不同的CPU逻辑核心上实现并行的效果,在这里举个例子:

        下面的例子是,只是用CPU的一个核心,先完成一个任务,再完成一个任务。

        设置逻辑核心为2,此时两个任务并行执行。

 

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

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

相关文章

【若依前后端分离】首页-多个按钮控制同一个图表

示例图&#xff1a;上面四个框可以点击 重要代码片段 &#xff1a; index_v1中 <panel-group handleSetLineChartData"handleSetLineChartData" :data"totalData"/> : 这是一个自定义的 Vue 组件。名称是 panel-group。handleSetLineChartData"…

WEB3.0:互联网的下一阶段

随着互联网的发展&#xff0c;WEB3.0时代正在逐步到来。本文将深入探讨WEB3.0的定义、特点、技术应用以及未来展望&#xff0c;为读者带来全新的思考。 一、什么是WEB3.0&#xff1f; WEB3.0可以被理解为互联网发展的下一阶段&#xff0c;是当前WEB2.0的升级版。相较于2.0时代…

有哪些软件可以限制应用安装呢?

在限制应用安装方面&#xff0c;有几种方法和工具可供选择&#xff0c;具体取决于你的需求和设备类型。以下是一些常见的方法和软件&#xff1a; 1. **家长控制功能**&#xff1a;操作系统如iOS、Android和Windows等都提供了家长控制功能&#xff0c;允许家长限制特定用户的应…

【go从入门到精通】作用域,包详解

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

性能分析-数据库(安装、索引、sql、执行过程)与磁盘知识(读、写、同时读写、内存速度测试)

数据库 数据库&#xff0c;其实是数据库管理系统dbms。 数据库管理系统&#xff0c; 常见&#xff1a; 关系型数据库&#xff1a; mysql、pg、 库的表&#xff0c;表与表之间有关联关系&#xff1b; 表二维表统一标准的SQL&#xff08;不局限于CRUD&#xff09;非关系型数据…

阿里云9元服务器租用收费价格表_免费云服务器领取

2024年最新阿里云服务器租用费用优惠价格表&#xff0c;轻量2核2G3M带宽轻量服务器一年61元&#xff0c;折合5元1个月&#xff0c;新老用户同享99元一年服务器&#xff0c;2核4G5M服务器ECS优惠价199元一年&#xff0c;2核4G4M轻量服务器165元一年&#xff0c;2核4G服务器30元3…

第P2周:CIFAR10彩色图片识别

第P2周&#xff1a;CIFAR10彩色图片识别 &#x1f368; 本文为&#x1f517;365 天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K 同学啊 &#x1f4cc;第P2周&#xff1a;彩色图片识别&#x1f4cc; 难度&#xff1a;小白入门⭐ 语言&#xff1a;Python…

QSFP-DD 和 QSFP+ / QSFP28 / QSFP56 / OSFP / CFP8 / COBO 之间的区别

&#x1f31f;QSFP-DD 作为400G 光模块的最小外形尺寸&#xff0c;提供业界最高的带宽密度&#xff0c;同时利用对低速 QSFP 可插拔模块和电缆的向后兼容性&#xff0c;使其在光纤制造商中很受欢迎。作为400G高速应用中最新的热门光收发器&#xff0c;QSFP-DD经常被拿来与QSFP5…

计算机视觉——DiffYOLO 改进YOLO与扩散模型的抗噪声目标检测

概述 物体检测技术在图像处理和计算机视觉中发挥着重要作用。其中&#xff0c;YOLO 系列等型号因其高性能和高效率而备受关注。然而&#xff0c;在现实生活中&#xff0c;并非所有数据都是高质量的。在低质量数据集中&#xff0c;更难准确检测物体。为了解决这个问题&#xff…

【报错】AttributeError: ‘NoneType‘ object has no attribute ‘pyplot_show‘(已解决)

【报错】AttributeError: ‘NoneType’ object has no attribute ‘pyplot_show’ 问题描述&#xff1a;python可视化出现下面报错 我的原始代码&#xff1a; import matplotlib.pyplot as pltplt.figure() plt.plot(x, y, bo-) plt.axis(equal) plt.xlabel(X) plt.ylabe…

基于LNMP部署wordpress

目录 一.环境准备 二.配置源并安装 三.配置Nginx 四.配置数据库 五.上传源码并替换 六.打开浏览器&#xff0c;输入虚拟机ip访问安装部署 七.扩展增加主题 一.环境准备 centos7虚拟机 关闭防火墙和seliunx stop firewalld #关闭防火墙 setenforce 0 …

软件设计师-基础知识科目-标准化与软件知识产权基本知识11

十一、标准化与软件知识产权基本知识&#xff1a; 知识产权&#xff1a; 主要包括&#xff1a;著作权及邻接权、专利权、工业品外观设计权、商标权、地理标志权、继承电路布图设计权。邻接权是指与著作权相邻近的权利&#xff0c;是指作品传播者&#xff0c;对其传播作品过程…

Unity TextMeshProUGUI 获取文本尺寸·大小

一般使用ContentSizeFitter组件自动变更大小 API 渲染前 Vector2 GetPreferredValues(string text)Vector2 GetPreferredValues(string text, float width, float height)Vector2 GetPreferredValues(float width, float height) 渲染后 Vector2 GetRenderedValues()Vector…

【安全】挖矿木马自助清理手册

一、什么是挖矿木马 挖矿木马会占用CPU进行超频运算&#xff0c;从而占用主机大量的CPU资源&#xff0c;严重影响服务器上的其他应用的正常运行。黑客为了得到更多的算力资源&#xff0c;一般都会对全网进行无差别扫描&#xff0c;同时利用SSH爆破和漏洞利用等手段攻击主机。 …

JavaEE初阶——多线程(二)

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 小比特 大梦想 此篇文章延续上一篇文章,与大家分享Thread常见的方法以及线程的状态相关知识 其他内容我们下一篇再见! 如果有错误或不足请您指出!!! 目录 3.Thread类及常见方法3.1Thread常见的构造方法3.2Thread…

STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978(2)

接前一篇文章&#xff1a;STM32H743VIT6使用STM32CubeMX通过I2S驱动WM8978&#xff08;1&#xff09; 本文参考以下文章及视频&#xff1a; STM32CbueIDE Audio播放音频 WM8978 I2S_stm32 cube配置i2s录音和播放-CSDN博客 STM32第二十二课&#xff08;I2S&#xff0c;HAL&am…

CLIP大模型图文检索——原理解读及代码实现

一. 核心思想 通过自然语言处理获得的监督信号可用于训练迁移效果出色的视觉模型。本论文的作者团队构建了一个庞大的图像文本配对数据集&#xff0c;其中包含400 million个图片文本的配对。利用最大规模的ViT-large模型&#xff0c;他们提出了CLIP&#xff08;Contrastive La…

机器学习和深度学习 -- 李宏毅(笔记与个人理解)Day 13

Day13 Error surface is rugged…… Tips for training :Adaptive Learning Rate critical point is not the difficult Root mean Square --used in Adagrad 这里为啥是前面的g的和而不是直接只除以当前呢? 这种方法的目的是防止学习率在训练过程中快速衰减。如果只用当前的…

自然语言处理NLP关键知识点

大家好&#xff0c;在人工智能出现之前&#xff0c;机器智能处理结构化的数据&#xff0c;例如 Excel 里的数据。但是网络中大部分的数据都是非结构化的&#xff0c;例如文章、图片、音频、视频等。在非结构数据中&#xff0c;文本的数量是最多的&#xff0c;他虽然没有图片和视…

信息系统项目管理师——第27章管理科学基础知识

1 最大流量问题[简单] 百度百科:最大流问题&#xff0c;一种组合最优化问题&#xff0c;就是要讨论如何充分利用装置的能力&#xff0c;使得运输的流量最大&#xff0c;以取得最好的效果。 教材P869:在起点和终点之间可能存在多条运输路径&#xff0c;总的最大流量就是求出各…