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

Go 协程为什么比进程和线程占用的系统资源低?

介绍

进程是一个程序在执行时所占据的独立虚拟内存空间,Linux为每个进程分配一个虚拟内存空间,包括栈、未使用的内存、堆、BSS、DATA和TEXT等。

线程可以看作是轻量级的进程,多个线程在一个进程中“共生”,每个线程拥有独立的栈空间,共享其他虚拟内存空间,因此线程间通信比较简单,也就是可以通过共享内存进行通信。

进程和线程都是CPU的执行单元,它们在内核态进行切换,切换成本较高。

协程是用户态的一种虚拟执行单元,在用户态切换执行流程,切换成本较低。


切换执行单元的成本

我们通过介绍线程和协程的切换流程,讲述为什么在内核态切换的成本较高,而在用户态切换的成本较低?

因为进程和线程都是内核态切换,并且进程切换成本比线程切换成本更高,所以只介绍线程切换和协程切换的切换成本。

内核态切换 - 线程

在了解线程在内核态切换之前,我们先了解一下什么是 CPU 时间片,在操作系统中,我们会安装很多软件,并且我们会同时使用多个软件,而 CPU 资源有限。

为了让多个软件可以在操作系统中同时运行,CPU 分成一个个的时间片,在每个时间片中运行一个软件的一个线程,因为时间片非常短,所以我们会感觉多个软件在同时运行。

在编写代码时,我们为了可以让程序被分配到更多的 CPU 资源,可以多创建一些线程,用于提升程序运行的效率。需要注意的是,线程并不是创建越多越好。

因为 CPU 在内核态切换执行单元(线程)时,会有时间成本,在进行切换执行单元时,需要保存寄存器中的数据,将原执行单元的状态保存,切换操作也会占用 CPU 资源(时间片),从而减少了供线程运行的 CPU 资源(时间片)。

除了时间成本之外,还会有性能开销,系统内核调度线程,需要用户空间和内核空间切换,因为只有拥有最高权限的内核空间才可以调度线程,限于篇幅,我们不再展开叙述。

用户态切换 - 协程

因为通过创建线程(执行单元),为程序争取更多的 CPU 资源,在线程切换时也会浪费 CPU 资源(时间成本),所以可以将执行单元不再在内核态运行,改为在用户态运行,也就是协程。

协程的切换成本较低,是因为切换比较简单,并且是在用户态进行切换,切换的时间成本较低(纳秒级),只需将当前协程的 CPU 寄存器的状态先保存起来,然后将需要 CPU 资源的协程的 CPU 寄存器的状态加载到 CPU 寄存器中。

关于 Go 协程的调度,我们在之前的文章中介绍过,此处不再赘述。


内存占用

除了 CPU 资源有限之外,内存资源也是有限的,所以我们还需要了解进程、线程、协程的内存占用。

读者朋友们应该知道 32 位操作系统只支持 4G 内存的内存条,这是因为进程在 32 位操作系统中最多只能占用 4G 内存,而在 64 位操作系统中可以占用更多内存。

线程占用内存一般是 10MB,不同的操作系统版本之间有些差异,区间在 4M - 64M。

协程占用内存最小,一个协程占用 2KB 左右的内存。


 4 

总结

本文我们主要介绍为什么 Go 协程比进程和线程占用的系统资源低,通过进程、线程、协程的 CPU 资源和内存占用的比较,发现无论是在切换时消耗的 CPU 资源(时间片),还是内存占用,Go 协程都有明显优势。

一句话总结就是 Go 协程的切换成本和内存占用比线程和进程都低。

需要注意的是,Go 协程占用系统资源低,并不代表可以无限创建 Go 协程。

参考资料:

  1. https://www.geeksforgeeks.org/time-slicing-in-cpu-scheduling/

  2. Virtual Memory

http://www.lryc.cn/news/122024.html

相关文章:

  • 性能测试—Jmeter工具
  • 【分布式系统】聊聊高性能设计
  • 自动驾驶数据集汇总
  • 面向对象的基本原则
  • C语言开发基础知识(一)
  • ​API网关类型与区别​
  • linux:nginx网站升级至http2
  • Flutter:屏幕适配
  • 中科亿海微ROM使用
  • Python接口自动化测试之UnitTest详解
  • python——案例17:判断某年是否是闰年
  • allure测试报告
  • Vue 路由懒加载
  • 软件设计师(七)面向对象技术
  • Qt中将信号封装在一个继承类中的方法
  • Docker介绍
  • C++红黑树
  • LangChain与大模型的学习ing
  • Go把Map转成对象
  • Java-网络编程
  • [数据集][目标检测]道路坑洼目标检测数据集VOC格式1510张2类别
  • 全网最详细,Pytest自动化测试框架-Fixture固件实战,你要的都有...
  • React 入门学习
  • VMware vCenter 6.5 断电后无法启动修复方案
  • c++ STL--算法,迭代器,容器适配器,仿函数
  • springcloud3 bus+springconfig 实现配置文件的动态刷新(了解)
  • SpringMVC的架构有什么优势?——视图与模型(二)
  • Vue中实现图片懒加载简单说明
  • zookeeper案例
  • 项目中使用git vscode GitHubDesktopSetup-x64