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

字节一面:go的协程相比线程,轻量在哪?的更多相关文章

  1. unity3D中协程和线程混合

    这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子: 大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了 ...

  2. day37协程与线程套接字通讯

    协程与线程套接字通讯基于多线程实现套接字服务端支持并发,服务端 from socket import * from threading import Thread def comunicate(con ...

  3. [Sw] 使用 Swoole Server task/协程 处理大数据量异步任务时注意

    关于 Buffered Query 和 Unbuffered Query:http://www.php.net/manual/zh/mysqlinfo.concepts.buffering.php 对 ...

  4. paip.提升性能---协程“微线程”的使用.

    paip.提升性能---协程的使用. 近乎无限并发的"微线程" 作者Attilax  艾龙,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:h ...

  5. Unity 协程与线程

    协程是不同步的 协程 不是 线程,协同程序是 不同步 的 一个线程在程序中和其他线程是异步运行的,在多处理器机器中一个线程可以同时与所有其他线程的实时运行其代码,这使得线程编程能够解决很复杂的事情,因 ...

  6. I/O多路复用、协程、线程、进程

    select注册fd,阻塞,当有fd状态改变时返回,确认对应的fd,做下一步处理.简单来说就是先注册,注册完后休眠并设置一个定时器醒来查看,有事件就通知来取,进行后续动作,没事件就继续睡,再设闹钟.用 ...

  7. lua协程----ngx-lua线程学习笔记

    --[[ - @desc lua数据输出 - @param string 字符串 - return string --]] function dump(v) if not __dump then fu ...

  8. (day31) Event+协程+进程/线程池

    目录 昨日回顾 GIL全局解释器锁 计算密集型和IO密集型 死锁现象 递归锁 信号量 线程队列 FOFI队列 LIFO队列 优先级队列 今日内容 Event事件 线程池与进程池 异步提交和回调函数 协 ...

  9. Lua 协程和线程区别

    协程就是协程,不是线程. CPU执行单位是线程,不是什么协程. 协程,是同步执行,不是并行,只是切了一个上下文了,为你保存原来的上下文而已. 切到第二个协程时,原来的协程处于挂起状态. 这个特指lua ...

随机推荐

  1. Nodejs ORM框架Sequelize(模型,关联表,事务,循环,及常见问题)

    1.建立连接 const Sequelize = require('sequelize'); const sequelize = new Sequelize('database', 'username ...

  2. 学习jsp篇:jsp简单实例之一注册

    编程环境:IDEA,Tomcat ,JavaEE 实例一.注册 1.先在IDEA建一个web工程(不懂的可以在网上搜,一大堆..)ServletTest,在工程目录下的web目录建一个文件夹regis ...

  3. SpringMVC主要组件

    1.DispatcherServlet:前端控制器,接收所有请求(如果配置/,则不包含jsp) 2.handlermapping:判断请求格式,判断希望具体要执行的那个方法 3.HanderAdapt ...

  4. SpringBoot+Dubbo+ZooKeeper+Maven入门实践

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11798626.html 注*** 本实例为仅适合初学者,关于dubbo和springboot以 ...

  5. 如何使Label显示时,一行顶部居中,两行靠左显示----董鑫

    有时我们会碰到这种情况,一个要根据内容显示一行还是两行,一行时还要靠着顶部再居中,比如下面 最左边的名称,要求是靠上的,如果按照正常的方式写的话,可能一行的话就会出现居中显示了,不会顶着头部显示. 我 ...

  6. 通过C#在控制台输出各种图形文字

    这不是要准备公司年会了嘛 每个部门抓壮丁,必须安排至少一个节目 想着上去唱首歌算了,被毙,没有部门特色 妈蛋,唱歌没特色,那隔壁在前线工作的部门要表演个啥,抄表? 冥思苦想之下,给节目加了点部门特色, ...

  7. HTTP流量神器Goreplay核心源码详解

    摘要:Goreplay 前称是 Gor,一个简单的 TCP/HTTP 流量录制及重放的工具,主要用 Go 语言编写. 本文分享自华为云社区<流量回放工具之 goreplay 核心源码分析> ...

  8. virtualenv 创建隔离工作环境

    在开发 Python 应用程序的时候,每个项目所需要的python版本和各种包依赖都可能不完全一样,我们当然希望当前运行环境只包含对当前项目有用的包依赖,以保证运行环境的干净.virtualenv就是 ...

  9. SaaS平台是什么,为什么字节、腾讯等大厂都在抢相关人才

    SaaS平台很多人可能没听说是什么,但是从事TO  B公司的员工来说,SaaS平台应该都有所耳闻.从2016年开始,腾讯开始发力TO B算起,到处在挖TO B公司的骨干人才,而熟悉SaaS平台的人才竞 ...

  10. Linux添加永久路由的方法

    通常我们使用route add -net添加临时路由.当系统重启,临时路由将丢失,重新配置路由带来了不必要的麻烦.可通过固化临时路由为永久路由的方法解决该问题. static-routes文件为路由固 ...