不做大哥好多年 不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核

逍遥子

不做大哥好多年
首页
  • MySQL
  • Redis
  • Elasticsearch
  • Kafka
  • Etcd
  • MongoDB
  • TiDB
  • RabbitMQ
  • 01.GO基础
  • 02.面向对象
  • 03.并发编程
  • 04.常用库
  • 05.数据库操作
  • 06.Beego框架
  • 07.Beego商城
  • 08.GIN框架
  • 09.GIN论坛
  • 10.微服务
  • 01.Python基础
  • 02.Python模块
  • 03.Django
  • 04.Flask
  • 05.SYL
  • 06.Celery
  • 10.微服务
  • 01.Java基础
  • 02.面向对象
  • 03.Java进阶
  • 04.Web基础
  • 05.Spring框架
  • 100.微服务
  • Docker
  • K8S
  • 容器原理
  • Istio
  • 数据结构
  • 算法基础
  • 算法题分类
  • 前置知识
  • PyTorch
  • 01.Python
  • 02.GO
  • 03.Java
  • 04.业务问题
  • 05.关键技术
  • 06.项目常识
  • 10.计算机基础
  • Linux基础
  • Linux高级
  • Nginx
  • KeepAlive
  • ansible
  • zabbix
  • Shell
  • Linux内核
  • GO基础

  • 面向对象

  • 并发编程

    • 01.goroutine介绍
    • 02.协程调度GRM模型
      • 01.线程调度
        • 1.1 早期单线程操作系统
        • 1.2 多进程/线程时代
        • 1.3 Go协程goroutine
        • 1.4 协程与线程区别
      • 02.调度器GMP模型
        • 2.1 GM模型
        • 2.2 GMP模型
      • 03.GPM流程分析
        • 3.1 P本地队列获取G
        • 3.2 本地队列中G移动到全局队列
        • 3.3 从其他P本地队列的G放到自己P队列
        • 3.4 M从P获取下一个G,不断重复
    • 03.协程基本使用
    • 04.Channel
    • 05.select
    • 06.并发安全和锁
    • 07.GO动态线程池
    • 08.goroutine编程
  • 常用库

  • 数据库操作

  • Beego框架

  • Beego商城

  • GIN框架

  • GIN论坛

  • 微服务

  • 设计模式

  • Go
  • 并发编程
xiaonaiqiang
2021-06-11
目录
01.线程调度
1.1 早期单线程操作系统
1.2 多进程/线程时代
1.3 Go协程goroutine
1.4 协程与线程区别
02.调度器GMP模型
2.1 GM模型
2.2 GMP模型
03.GPM流程分析
3.1 P本地队列获取G
3.2 本地队列中G移动到全局队列
3.3 从其他P本地队列的G放到自己P队列
3.4 M从P获取下一个G,不断重复

02.协程调度GRM模型

# 01.线程调度

# 1.1 早期单线程操作系统

  • 一切的软件都是跑在操作系统上,真正用来干活(计算)的是CPU。

  • 早期的操作系统每个程序就是一个进程,知道一个程序运行完,才能进行下一个进程,就是“单进程时代”

  • 一切的程序只能串行发生。

# 1.2 多进程/线程时代

  • 在多进程/多线程的操作系统中,就解决了阻塞的问题,因为一个进程阻塞cpu可以立刻切换到其他进程中去执行

  • 而且调度cpu的算法可以保证在运行的进程都可以被分配到cpu的运行时间片

  • 这样从宏观来看,似乎多个进程是在同时被运行。

  • 但新的问题就又出现了,进程拥有太多的资源,进程的创建、切换、销毁,都会占用很长的时间

  • CPU虽然利用起来了,但如果进程过多,CPU有很大的一部分都被用来进行进程调度了

  • 大量的进程/线程出现了新的问题

    • 高内存占用
    • 调度的高消耗CPU
    • 进程虚拟内存会占用4GB[32位操作系统], 而线程也要大约4MB

# 1.3 Go协程goroutine

  • Go中,协程被称为goroutine,它非常轻量,一个goroutine只占几KB,并且这几KB就足够goroutine运行完

  • 这就能在有限的内存空间内支持大量goroutine,支持了更多的并发

  • 虽然一个goroutine的栈只占几KB,但实际是可伸缩的,如果需要更多内容,runtime会自动为goroutine分配。

  • Goroutine特点:

    • 占用内存更小(几kb)
    • 调度更灵活(runtime调度)

# 1.4 协程与线程区别

  • 协程跟线程是有区别的,线程由CPU调度是抢占式的
  • 协程由用户态调度是协作式的,一个协程让出CPU后,才执行下一个协程

# 02.调度器GMP模型

  • G:goroutine(协程)
  • M:thread(内核线程,不是用户态线程)
  • P:processer(调度器)

# 2.1 GM模型

  • G(协程),通常在代码里用 go 关键字执行一个方法,那么就等于起了一个G。

  • M(内核线程),操作系统内核其实看不见G和P,只知道自己在执行一个线程。

  • G和P都是在用户层上的实现。

  • 并发量小的时候还好,当并发量大了,这把大锁,就成为了性能瓶颈。

  • GPM由来
    • 基于没有什么是加一个中间层不能解决的思路,golang在原有的GM模型的基础上加入了一个调度器P
    • 可以简单理解为是在G和M中间加了个中间层
    • 于是就有了现在的GMP模型里的P

# 2.2 GMP模型

# 03.GPM流程分析

  • 我们通过 go func()来创建一个goroutine;

# 3.1 P本地队列获取G

  • M想要运行G,就得先获取P,然后从P的本地队列获取G

# 3.2 本地队列中G移动到全局队列

  • 新建 G 时,新G会优先加入到 P 的本地队列;
  • 如果本地队列满了,则会把本地队列中一半的 G 移动到全局队列

# 3.3 从其他P本地队列的G放到自己P队列

  • 如果全局队列为空时,M 会从其他 P 的本地队列偷(stealing)一半G放到自己 P 的本地队列。

# 3.4 M从P获取下一个G,不断重复

  • M 运行 G,G 执行之后,M 会从 P 获取下一个 G,不断重复下去

上次更新: 2024/3/13 15:35:10
01.goroutine介绍
03.协程基本使用

← 01.goroutine介绍 03.协程基本使用→

最近更新
01
04.数组双指针排序_子数组
03-25
02
08.动态规划
03-25
03
06.回溯算法
03-25
更多文章>
Theme by Vdoing | Copyright © 2019-2025 逍遥子 技术博客 京ICP备2021005373号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式