字节一面:go的协程相比线程,轻量在哪?
1. 用户态和内核态
Linux整个体系分为用户态和内核态(或者叫用户空间和内核空间), 那内核态究竟是什么呢?
本质上我们所说的内核态, 它是一种特殊的软件程序,特殊在哪?
统筹计算机的硬件资源,例如协调CPU资源、分配内存资源、并且提供稳定的环境供应用程序运行。
2. 为什么线程切换会导致用户态和内核态的切换?
- 线程是cpu调度的基本单位,进程是资源占有的基本单位。
- 因为线程中的代码是在用户态运行,而线程的调度是在内核态,所以线程切换会触发用户态和内核态的切换。
- 线程上下文切换的代价是高昂的:上下文切换的延迟取决于不同的因素,大概是50到100 ns左右,考虑到硬件平均在每个核心上每ns执行12条指令,那么一次上下文切换可能会花费600到1200条指令的延迟时间。
3. 导致线程上下文切换的时机
| <1>. 自发性上下文切换 | 自发性上下文切换指线程由于自身因素导致的切出 |
|---|---|
| Thread.sleep() | 线程主动休眠 |
| object.wait() | 线程等待锁 |
| Thread.yield() | 当前线程主动让出CPU,如果有其他就绪线程就执行其他线程,如果没有则继续当前线程 |
| oThread.join() | 阻塞发起调用的线程,直到oThread执行完毕 |
| <2>. 非自发性上下文切换:线程由于线程调度器的原因被迫切出 |
|---|
| 线程的时间片用完 |
| 高优先级线程抢占 |
| 虚拟机的垃圾回收动作 |
4. 线程切换的开销
| <1>. 直接开销 |
|---|
| 保存/恢复上下文所需的开销 |
| 线程调度器调度线程的开销 |
| <2>. 间接开销 |
|---|
| 重新加载高速缓存 |
| 上下文切换可能导致 一级缓存被冲刷,写入下一级缓存或内存 |
4. go的协程轻量级体现在哪?
如上面所述,线程切换会导致 用户态和内核态的切换,其中内核态耗时较长,且不受用户代码控制。
go将goroutine的调度维持在用户态, 这是由GPM中的P Process来完成的,做用户态任务的调度器,功能类比于常规的操作系统线程调度器,所以又被称为逻辑处理器。
P 是G、M之间的桥梁,调度器对于goroutine的调度,很明显也会有切换,这个切换是很轻量的: 只涉及PC SP DX三个寄存器的值的修改;而对比线程的上下文切换则需要陷入内核模式、以及16个寄存器的刷新。
5. GO GMP 调度方式
- 由逻辑处理器P调度协程G进系统线程M (若本地队列没有G,从其他队列/全局队列偷取G),
- 线程M执行G, 遇到[系统调用], G和M分离,拿新的M去接管原逻辑处理器P
请仔细阅读上图,出处不可考证,感谢原图作者。
这里特意指出网络IO操作不会走上图的模型,否则要分配的系统线程M依然很多,程序很快就爆满了。这时G会和逻辑处理器P分离,并移动到netpoller,一旦网络轮询器通知网络读/写就绪,对应G就会重新分配到逻辑器处理器上来完成操作, 在此期间原系统线程M可以去做别的G。
ref
- https://blog.csdn.net/No_Game_No_Life_/article/details/106100813
- https://zhuanlan.zhihu.com/p/261807834
- https://chende.ren/2020/12/27221039-008-gmp-model.html
- https://studygolang.com/articles/12328
- https://www.jianshu.com/p/cc3c0fefee43
字节一面:go的协程相比线程,轻量在哪?的更多相关文章
- unity3D中协程和线程混合
这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子: 大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了 ...
- day37协程与线程套接字通讯
协程与线程套接字通讯基于多线程实现套接字服务端支持并发,服务端 from socket import * from threading import Thread def comunicate(con ...
- [Sw] 使用 Swoole Server task/协程 处理大数据量异步任务时注意
关于 Buffered Query 和 Unbuffered Query:http://www.php.net/manual/zh/mysqlinfo.concepts.buffering.php 对 ...
- paip.提升性能---协程“微线程”的使用.
paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...
- Unity 协程与线程
协程是不同步的 协程 不是 线程,协同程序是 不同步 的 一个线程在程序中和其他线程是异步运行的,在多处理器机器中一个线程可以同时与所有其他线程的实时运行其代码,这使得线程编程能够解决很复杂的事情,因 ...
- I/O多路复用、协程、线程、进程
select注册fd,阻塞,当有fd状态改变时返回,确认对应的fd,做下一步处理.简单来说就是先注册,注册完后休眠并设置一个定时器醒来查看,有事件就通知来取,进行后续动作,没事件就继续睡,再设闹钟.用 ...
- lua协程----ngx-lua线程学习笔记
--[[ - @desc lua数据输出 - @param string 字符串 - return string --]] function dump(v) if not __dump then fu ...
- (day31) Event+协程+进程/线程池
目录 昨日回顾 GIL全局解释器锁 计算密集型和IO密集型 死锁现象 递归锁 信号量 线程队列 FOFI队列 LIFO队列 优先级队列 今日内容 Event事件 线程池与进程池 异步提交和回调函数 协 ...
- Lua 协程和线程区别
协程就是协程,不是线程. CPU执行单位是线程,不是什么协程. 协程,是同步执行,不是并行,只是切了一个上下文了,为你保存原来的上下文而已. 切到第二个协程时,原来的协程处于挂起状态. 这个特指lua ...
随机推荐
- C字符串倒置-中部对称
问题如图 Code #include<stdio.h> #include<string.h> #define MAX_LENGTH 10//最大字符串长度 void inver ...
- webpack热更新 同时导出文件到本地
webpack 配置热更新后,文件配置导出到本地 安装 npm i webpack-dev-server-output --save-dev 引入 const WebpackDevServerOutp ...
- spring 注解注入bean
通过注解方式注入bean,需要在配置类下注入bean 第一步,配置扫描文件夹 首先要在spring.xml中配置需要扫描的配置类 <context:componenet-scan base-pa ...
- Java线程--BlockingQueue使用
原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871704.html Java线程--BlockingQueue使用 阻塞队列就是内容满了之 ...
- Xcode 插件推荐
1. Alcatraz(建议安装,以下插件都可以在Alcatraz下载安装) 使用Alcatraz来下载管理Xcode插件, 2.下载安装注释插件VVDocumenter-Xcode. 3.使用代码对 ...
- abp vnext 调试
在用Abp或者asp.net core 开发过程中,难免会遇到稀奇古怪的问题,需要对底层源代码进行调试,下面就教大家如何通过配置Visual Studio 2019来进行调试: 首先我们通过查看Abp ...
- WEB前端开发--2(HTML基础)
HTML基础 HTML不分大小写 1.HTML概述 HTML(HyperText MarkUp Language)"超文本标记语言",他是制作网页的标准语言 1.1 标签--元素 ...
- 「游记」NOIP 2021 爆零记
推荐访问本人自建博客 \(\text{cjwen.top}\) 欧拉欧拉欧拉欧拉欧拉欧拉欧拉欧拉,第一次参加 \(NOIP\),欧拉欧拉欧拉欧拉欧拉欧拉欧拉欧拉. 第一题比较简单,用类似于筛质数的做法 ...
- 基于GDAL库,读取.nc文件(以海洋表温数据为例)C++版
对于做海洋数据处理的同学,会经常遇到nc格式的文件,nc文件的格式全称是NetCDF,具体的详细解释请查询官网[https://www.unidata.ucar.edu/software/netcdf ...
- UVM宏
1.注册宏 // 注册object类 `uvm_object_utils(类名) `uvm_object_parm_utils(类名) `uvm_object_utils_begin(类名) // 注 ...