字节一面: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 ...
随机推荐
- Springboot整合RocketMQ解决分布式事务
直接上代码: 代码结构如下: 依次贴出相关类: DataSource1Config: package com.example.demo.config;import org.apache.ibatis. ...
- Android编译implement、api 和compile区别【转】
感谢大佬:https://blog.csdn.net/fengyeNom1/article/details/81903186 前言 2017 年google 后,Android studio 版本更新 ...
- VC 常用
转载请注明来源:https://www.cnblogs.com/hookjc/ ------------------------------------------------------------ ...
- autorelease基本使用
1.autorelease基本概念 autorelease是一种支持引用计数的内存管理方式,只要给对象发送一条autorelease消息,会将对象放到一个自动释放池中,当自动释放池被销毁时,会对池子里 ...
- 如何实现固定宽高的DOM元素的水平垂直居中
效果:
- Innodb之索引与算法
目录 一.概述 二.数据结构与算法 1.二分查找 2.二叉查找树和平衡二叉树 1)二叉查找树 2)平衡二叉树 三.B+树 1.B+树完整定义 2.关于 M 和 L的选定案例 四.B+树索引 1.聚集索 ...
- Java如何实现消费数据隔离?
我是3y,一年CRUD经验用十年的markdown程序员常年被誉为优质八股文选手 今天继续更新austin项目,如果还没看过该系列的同学可以点开我的历史文章回顾下,在看的过程中不要忘记了点赞哟!建议 ...
- v77.01 鸿蒙内核源码分析(消息封装篇) | 剖析LiteIpc(上)进程通讯内容 | 新的一年祝大家生龙活虎 虎虎生威
百篇博客分析|本篇为:(消息封装篇) | 剖析LiteIpc进程通讯内容 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁 ...
- 用 Beep 函数让主板“唱”《生日歌》
用 Beep 函数,让你的主板也会"唱歌".Beep 可以通过控制主板扬声器的发声频率和节拍来演奏美妙的旋律.本文就通过C#演示,调用Beep函数,演奏生日快乐歌.首先我们来看下 ...
- CobaltStrike逆向学习系列(12):RDI 任务发布流程分析
这是[信安成长计划]的第 12 篇文章 0x00 目录 0x01 任务构建 0x02 结果处理 0x03 功能 DLL 分析 之前的分析都是针对整个 CS 的框架来进行的,但是功能也是整个 C2 中相 ...