GO——GPM

2024-01-26 08:28
文章标签 go gpm

本文主要是介绍GO——GPM,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

参考:https://juejin.cn/post/6844904130398404616

并发模型

参考:https://zhuanlan.zhihu.com/p/137339439

  • 多进程
    • 要点
      • 主进程监听
      • 每进来一个请求,fork子进程处理
    • 缺点
      • 进程占用高,服务器负载高
      • 进程间通信困难
        • 参考;https://www.jianshu.com/p/c1015f5ffa74
    • 示例
      • apache的web容器
  • 多线程与锁
    • 相关概念
      • 线程安全
        • 参考:https://www.huaweicloud.com/articles/6b47975275ab65b2c0a1c358d6369715.html
        • 代码多线程运行时,每次运行的变量预期、结果和单线程运行时是一样的,就是线程安全的
        • 线程安全问题由全局变量和静态变量引起
      • 模型
        • 互斥锁
        • 生产者-消费者
        • 同步
    • 优点
      • 易理解
      • 容易实现,基础语言库都支持
      • 其他并非模型的基础
    • 缺点
      • 难测试,容易隐藏某些问题
      • 线程创建、销毁的开销也不小
  • 单线程回调和事件轮询模型
    • 示例
      • nginx
        • 参考:https://www.modb.pro/db/47207
        • 多进程单线程
        • 每个worker进程采用异步非阻塞模式
        • 事件驱动模型: 异步非阻塞采用epoll:描述符列表管理交给内核,内核有事件发生,通知给进程
        • 多进程结构、异步非阻塞的处理机制和采用事件驱动模型(epoll)就是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已满
      • 放入全局队列
  • M处理完了之后
    • 1、先取对应的P的队列
    • 2、再取全局队列
    • 3、最后取其他P的队列(偷)
    • 如果还是取不到,断开与P的连接,进入idle

特点

  • 抢占式调度
    • 在runtime.main中会创建一个额外m运行sysmon函数,抢占就是在sysmon中实现的。
  • G长久阻塞在M,runtime会新建M,P会把其他G挂载到新M。
    • 旧G阻塞完成或被认为死掉,回收M

这篇关于GO——GPM的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/646192

相关文章

Go Playground 在线编程环境

For all examples in this and the next chapter, we will use Go Playground. Go Playground represents a web service that can run programs written in Go. It can be opened in a web browser using the follow

go基础知识归纳总结

无缓冲的 channel 和有缓冲的 channel 的区别? 在 Go 语言中,channel 是用来在 goroutines 之间传递数据的主要机制。它们有两种类型:无缓冲的 channel 和有缓冲的 channel。 无缓冲的 channel 行为:无缓冲的 channel 是一种同步的通信方式,发送和接收必须同时发生。如果一个 goroutine 试图通过无缓冲 channel

如何确定 Go 语言中 HTTP 连接池的最佳参数?

确定 Go 语言中 HTTP 连接池的最佳参数可以通过以下几种方式: 一、分析应用场景和需求 并发请求量: 确定应用程序在特定时间段内可能同时发起的 HTTP 请求数量。如果并发请求量很高,需要设置较大的连接池参数以满足需求。例如,对于一个高并发的 Web 服务,可能同时有数百个请求在处理,此时需要较大的连接池大小。可以通过压力测试工具模拟高并发场景,观察系统在不同并发请求下的性能表现,从而

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

Go Select的实现

select语法总结 select对应的每个case如果有已经准备好的case 则进行chan读写操作;若没有则执行defualt语句;若都没有则阻塞当前goroutine,直到某个chan准备好可读或可写,完成对应的case后退出。 Select的内存布局 了解chanel的实现后对select的语法有个疑问,select如何实现多路复用的,为什么没有在第一个channel操作时阻塞 从而导

Go Channel的实现

channel作为goroutine间通信和同步的重要途径,是Go runtime层实现CSP并发模型重要的成员。在不理解底层实现时,经常在使用中对channe相关语法的表现感到疑惑,尤其是select case的行为。因此在了解channel的应用前先看一眼channel的实现。 Channel内存布局 channel是go的内置类型,它可以被存储到变量中,可以作为函数的参数或返回值,它在r

Go 数组赋值问题

package mainimport "fmt"type Student struct {Name stringAge int}func main() {data := make(map[string]*Student)list := []Student{{Name:"a",Age:1},{Name:"b",Age:2},{Name:"c",Age:3},}// 错误 都指向了最后一个v// a

Go组合

摘要 golang并非完全面向对象的程序语言,为了实现面向对象的继承这一神奇的功能,golang允许struct间使用匿名引入的方式实现对象属性方法的组合 组合使用注意项 使用匿名引入的方式来组合其他struct 默认优先调用外层方法 可以指定匿名struct以调用内层方法 代码 package mainimport ("fmt")type People struct{}type Pe

Go语言构建单链表

package mainimport "fmt"type ListNode struct {Val intNext *ListNode}func main() {list := []int{2,4,3}head := &ListNode{Val:list[0]}tail := head //需要头尾两个指针for i:=1;i<len(list);i++ {//方法一 数组直接构建链表tai

Go 在orm中使用反射

作为静态语言,golang 稍显笨拙,还好 go 的标准包reflect(反射)包弥补了这点不足,它提供了一系列强大的 API,能够根据执行过程中对象的类型来改变程序控制流。本文将通过设计并实现一个简易的 mysql orm 来学习它,要求读者了解mysql基本知识,并且跟我一样至少已经接触 golang 两到三个月。 orm 这个概念相信同学们都非常熟悉,尤其是写过rails的同学,对acti