Go 协程为什么比进程和线程占用的系统资源低?
1
介绍
进程是一个程序在执行时所占据的独立虚拟内存空间,Linux为每个进程分配一个虚拟内存空间,包括栈、未使用的内存、堆、BSS、DATA和TEXT等。
线程可以看作是轻量级的进程,多个线程在一个进程中“共生”,每个线程拥有独立的栈空间,共享其他虚拟内存空间,因此线程间通信比较简单,也就是可以通过共享内存进行通信。
进程和线程都是CPU的执行单元,它们在内核态进行切换,切换成本较高。
协程是用户态的一种虚拟执行单元,在用户态切换执行流程,切换成本较低。
2
切换执行单元的成本
我们通过介绍线程和协程的切换流程,讲述为什么在内核态切换的成本较高,而在用户态切换的成本较低?
因为进程和线程都是内核态切换,并且进程切换成本比线程切换成本更高,所以只介绍线程切换和协程切换的切换成本。
内核态切换 - 线程
在了解线程在内核态切换之前,我们先了解一下什么是 CPU 时间片,在操作系统中,我们会安装很多软件,并且我们会同时使用多个软件,而 CPU 资源有限。
为了让多个软件可以在操作系统中同时运行,CPU 分成一个个的时间片,在每个时间片中运行一个软件的一个线程,因为时间片非常短,所以我们会感觉多个软件在同时运行。
在编写代码时,我们为了可以让程序被分配到更多的 CPU 资源,可以多创建一些线程,用于提升程序运行的效率。需要注意的是,线程并不是创建越多越好。
因为 CPU 在内核态切换执行单元(线程)时,会有时间成本,在进行切换执行单元时,需要保存寄存器中的数据,将原执行单元的状态保存,切换操作也会占用 CPU 资源(时间片),从而减少了供线程运行的 CPU 资源(时间片)。
除了时间成本之外,还会有性能开销,系统内核调度线程,需要用户空间和内核空间切换,因为只有拥有最高权限的内核空间才可以调度线程,限于篇幅,我们不再展开叙述。
用户态切换 - 协程
因为通过创建线程(执行单元),为程序争取更多的 CPU 资源,在线程切换时也会浪费 CPU 资源(时间成本),所以可以将执行单元不再在内核态运行,改为在用户态运行,也就是协程。
协程的切换成本较低,是因为切换比较简单,并且是在用户态进行切换,切换的时间成本较低(纳秒级),只需将当前协程的 CPU 寄存器的状态先保存起来,然后将需要 CPU 资源的协程的 CPU 寄存器的状态加载到 CPU 寄存器中。
关于 Go 协程的调度,我们在之前的文章中介绍过,此处不再赘述。
3
内存占用
除了 CPU 资源有限之外,内存资源也是有限的,所以我们还需要了解进程、线程、协程的内存占用。
读者朋友们应该知道 32 位操作系统只支持 4G 内存的内存条,这是因为进程在 32 位操作系统中最多只能占用 4G 内存,而在 64 位操作系统中可以占用更多内存。
线程占用内存一般是 10MB,不同的操作系统版本之间有些差异,区间在 4M - 64M。
协程占用内存最小,一个协程占用 2KB 左右的内存。
4
总结
本文我们主要介绍为什么 Go 协程比进程和线程占用的系统资源低,通过进程、线程、协程的 CPU 资源和内存占用的比较,发现无论是在切换时消耗的 CPU 资源(时间片),还是内存占用,Go 协程都有明显优势。
一句话总结就是 Go 协程的切换成本和内存占用比线程和进程都低。
需要注意的是,Go 协程占用系统资源低,并不代表可以无限创建 Go 协程。
参考资料:
-
https://www.geeksforgeeks.org/time-slicing-in-cpu-scheduling/
-
Virtual Memory
相关文章:
Go 协程为什么比进程和线程占用的系统资源低?
1 介绍 进程是一个程序在执行时所占据的独立虚拟内存空间,Linux为每个进程分配一个虚拟内存空间,包括栈、未使用的内存、堆、BSS、DATA和TEXT等。 线程可以看作是轻量级的进程,多个线程在一个进程中“共生”,每个线程拥有独立的…...
性能测试—Jmeter工具
文章目录 性能测试1. 术语介绍2. 方法3. 应用场景4. 工具(Jmeter)4.1 介绍4.2 元件和组件4.2.2 元件4.2.1 组件 4.3 作用域4.4 参数化4.5 执行脚本 性能测试 1. 术语介绍 响应时间(Response time):对请求作出响应所需要的时间。 在互联网上对…...
【分布式系统】聊聊高性能设计
每个程序员都应该知道的数字 高性能 对于以上的数字,其实每个程序员都应该了解,因为只有了解这些基本的数字,才能知道对于CPU、内存、磁盘、网络之间数据读写的时间。1000ms 1S。毫秒->微秒->纳秒-秒->分钟 为什么高性能如此重要的…...
自动驾驶数据集汇总
1.Nuscenes 数据集链接:nuScenes nuscenes数据集下有多个任务,涉及Detection(2D/3D)、Tracking、prediction、激光雷达分割、全景任务、规划控制等多个任务; nuScenes数据集是一个具有三维目标注释的大型自动驾驶数…...
面向对象的基本原则
背景 面向对象是抽象技术的一种实现,将对象作为真实世界中实体的抽象,代表了特定的一块密集而内聚的信息。在面向对象设计及实现中,重点考虑的就是如何做到关注点分离。因为对象内的联系通常比对象间的联系更强。关注点分离就是将对象中高频…...
C语言开发基础知识(一)
文章目录 数据类型宏变量函数inline 内联函数static 关键字的作用const 关键字的作用extern 关键字的作用volatile 关键字的作用include 关键字的作用数组、字符串指针堆内存管理结构体文件操作数据类型 C语言中数据类型分有符号和无符号,默认是有符号的。 有符号类型: 数据…...
API网关类型与区别
什么是API网关? 在现代软件架构中,API(应用程序编程接口)网关起着重要的作用。它是一个中间层,用于管理和控制应用程序之间的通信。API网关可以提供一些关键功能,如流量控制,安全认证ÿ…...
linux:nginx网站升级至http2
参考: 怎样把网站升级到http/2 - 知乎 HTTP/2 与 HTTP/1.1:它们如何影响 Web 性能? | Cloudflare 总结: nginx.conf修改 http2需要ssl支持 listen 443 ssl http2;...
Flutter:屏幕适配
flutter_screenutil flutter_screenutil是一个用于在Flutter应用程序中进行屏幕适配的工具包。它旨在帮助开发者在不同屏幕尺寸和密度的设备上创建响应式的UI布局。 flutter_screenutil提供了一些用于处理尺寸和间距的方法,使得开发者可以根据设备的屏幕尺寸和密度…...
中科亿海微ROM使用
标题 ROM(Read-Only Memory,只读存储器)是一种在FPGA(Field-Programmable Gate Array,现场可编程门阵列)中常用的存储器类型。与RAM(Random Access Memory,机存取存储器)…...
Python接口自动化测试之UnitTest详解
基本概念 UnitTest单元测试框架是受到JUnit的启发,与其他语言中的主流单元测试框架有着相似的风格。其支持测试自动化,配置共享和关机代码测试。支持将测试样例聚合到测试集中,并将测试与报告框架独立。 它分为四个部分test fixture、TestC…...
python——案例17:判断某年是否是闰年
案例17:判断某年是否是闰年 判断依据:闰年就是能被400整除,或者能被4整除的年份numint(input(输入年份:))if num%1000: if num%4000: #整百年份的判断print("%s年是闰年"%num) #…...
allure测试报告
使用pytest结合Allure进行测试报告生成的简单教程 allure测试报告 Allure基于Java开发,因此我们需要提前安装Java 8或以上版本的环境。 ◆安装allure-pytest插件在DOS窗口输入命令“pip3 install allure-pytest”,然后按“Enter”键。 下载安装Allure…...
Vue 路由懒加载
Vue 路由懒加载 随着 Web 应用的复杂性不断增加,性能优化成为了开发人员必须面对的挑战之一。Vue 路由懒加载是一项关键技术,它可以帮助我们提高 Web 应用的加载速度,从而提升用户体验。 在本篇技术博文中,我们将深入探讨 Vue 路…...
软件设计师(七)面向对象技术
面向对象: Object-Oriented, 是一种以客观世界中的对象为中心的开发方法。 面向对象方法有Booch方法、Coad方法和OMT方法等。推出了同一建模语言UML。 面向对象方法包括面向对象分析、面向对象设计和面向对象实现。 一、面向对象基础 1、面向对象的基本…...
Qt中将信号封装在一个继承类中的方法
QLabel标签类对应的信号如下: Qt中标签是没有双击(double Click)这个信号的; 需求一:若想双击标签使其能够改变标签中文字的内容,那么就需要自定义一个“双击”信号,并将其封装在QLabel类的派生…...
Docker介绍
1. docker是什么 1.1 为什么会有docker出现? 假设你在开发一个项目的时候,你使用的是windows系统而且你的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。你正在开发的应用依赖于你当前的配置而且还要依赖于某些配置文件。此外…...
C++红黑树
一、红黑树的概念 红黑树是一种二叉搜索树,在其每个节点上增加一个存储位用于表示节点的颜色,可以是Red或Black 通过对任何一条从根到叶子的路径上的各个节点着色方式的限制,红黑树确保没有一条路径比其他路径长两倍 红黑树的性质ÿ…...
LangChain与大模型的学习ing
大模型的菜鸟初学习 一、问题记录1、库的版本问题 二、实例记录1、公司名生成2、提示模板的使用3、LLM Chain4、LLMMemory5、聊天语言API 参考资料 一、问题记录 1、库的版本问题 openai.error.APIConnectionError: Error communicating with OpenAI: HTTPSConnectionPool(ho…...
Go把Map转成对象
最近使用了Redis的Hash,把一个对象给存储到了hash里面,具体如下: 现在需要从RedisHash缓存里面把结果给取出来,同时赋值到一个对象上面 result, err : global.GVA_REDIS.HGetAll(context.Background(), key).Result() 问题是resul…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...
