GO——GPM
【代码】GO——GPM。
·
参考:https://juejin.cn/post/6844904130398404616
并发模型
参考:https://zhuanlan.zhihu.com/p/137339439
- 多进程
- 要点
- 主进程监听
- 每进来一个请求,fork子进程处理
- 缺点
- 进程占用高,服务器负载高
- 进程间通信困难
- 示例
- apache的web容器
- 要点
- 多线程与锁
- 相关概念
- 线程安全
- 参考:https://www.huaweicloud.com/articles/6b47975275ab65b2c0a1c358d6369715.html
- 代码多线程运行时,每次运行的变量预期、结果和单线程运行时是一样的,就是线程安全的
- 线程安全问题由全局变量和静态变量引起
- 线程安全
- 锁
- 模型
- 互斥锁
- 生产者-消费者
- 同步
- 模型
- 优点
- 易理解
- 容易实现,基础语言库都支持
- 其他并非模型的基础
- 缺点
- 难测试,容易隐藏某些问题
- 线程创建、销毁的开销也不小
- 相关概念
- 单线程回调和事件轮询模型
- 示例
- nginx
- 参考:https://www.modb.pro/db/47207
- 多进程单线程
- 每个worker进程采用异步非阻塞模式
- 事件驱动模型: 异步非阻塞采用epoll:描述符列表管理交给内核,内核有事件发生,通知给进程
- 多进程结构、异步非阻塞的处理机制和采用事件驱动模型(epoll)就是Nginx实现高并发的秘密所在。
- nginx
- 示例
- 函数式编程
- Clojure之道
- actor
- 通信顺序进程(CSP)
- 一种描述并发性系统之间进行交互的模型
- 参考:https://bbs.huaweicloud.com/blogs/292354
- 核心观念:
- 两个并发执行的实体通过通道channel连接起来,所有的消息都通过channel传输
- 参考:https://juejin.cn/post/6844904130398404616
- 数据级并行
- Lambda架构
GPM调度模型
GPM
- Goroutinue
- go关键字创建的实体,是一个结构体,保存了堆栈信息
- 语言层面实现
- 组成
- 执行栈
- 状态
- 当前占用线程
- 调度相关数据
sched gobuf
- 协程切换,恢复上下文的时候使用
- Processor
- 处理器,简历G、M的联系
- 功能
- machine和goroutine的连接
- 数量
- 默认与GOMAXPROCS一致
- 组成
- 性能追踪
- 垃圾回收
- 计时器
- 处理器待运行队列
- goroutine列表
- Machine
- 对应操作系统的线程
- 最多线程数:GOMAXPROCS,通常设置成内核数
- 结构体组成:
- g0,重要,深度参与调度过程,goroutine的创建、内存分配
- curg,重要,当前线程正在执行的goroutine
- p,正在允许的处理器
- nextp,暂存的处理器
- old,系统调用之前的处理器
运行过程
- 启动
- 默认四个线程(M)、四个处理器(P)
- goroutine创建
- 函数体地址
- 参数起始地址
- 参数长度
- goroutine进入队列
- 调度相关信息更新
- 这里进入的是P的私有队列
- 又有其他goroutine进来
- 如果还有空闲P
- 依次放入空闲P
- 如果P已满
- 放入全局队列
- 如果还有空闲P
- M处理完了之后
- 1、先取对应的P的队列
- 2、再取全局队列
- 3、最后取其他P的队列(偷)
- 如果还是取不到,断开与P的连接,进入idle
特点
- 抢占式调度
- 在runtime.main中会创建一个额外m运行sysmon函数,抢占就是在sysmon中实现的。
- G长久阻塞在M,runtime会新建M,P会把其他G挂载到新M。
- 旧G阻塞完成或被认为死掉,回收M
更多推荐
已为社区贡献1条内容
所有评论(0)