首页 > 资料专栏 > 经营 > 运营治理 > 其他资料 > Go语言实践-RuntimePPTX

Go语言实践-RuntimePPTX

chendeg***
V 实名认证
内容提供者
热门搜索
资料大小:8032KB(压缩后)
文档格式:PPTX(105页)
资料语言:中文版/英文版/日文版
解压密码:m448
更新时间:2024/9/14(发布于上海)

类型:金牌资料
积分:--
推荐:升级会员

   点此下载 ==>> 点击下载文档


文本描述
毛剑
Go进阶训练营 第13课 Go 语言实践 - Runtime
Goroutine 原理 内存分配原理 GC 原理 Channel 原理
Goroutine 原理
Goroutine GMP 调度模型 Work-stealing 调度算法 Goroutine Lifecycle
goroutine 定义
“Goroutine 是一个与其他 goroutines 并行运行在同一地址空间的 Go 函数或方法。一个运行的程序由一个或更多个 goroutine 组成。它与线程、协程、进程等不同。它是一个 goroutine” —— Rob Pike Goroutines 在同一个用户地址空间里并行独立执行 functions,channels 则用于 goroutines 间的通信和同步访问控制。
goroutine 和 thread 的区别?
内存占用,创建一个 goroutine 的栈内存消耗为 2 KB(Linux AMD64 Go v1.4后),运行过程中,如果栈空间不够用,会自动进行扩容。 创建一个 thread 为了尽量避免极端情况下操作系统线程栈的溢出,默认会为其分配一个较大的栈内存( 1 - 8 MB 栈内存,线程标准 POSIX Thread),而且还需要一个被称为 “guard page” 的区域用于和其他 thread 的栈空间进行隔离。而栈内存空间一旦创建和初始化完成之后其大小就不能再有变化,这决定了在某些特殊场景下系统线程栈还是有溢出的风险。 创建/销毁,线程创建和销毀都会有巨大的消耗,是内核级的交互(trap)。 POSIX 线程(定义了创建和操纵线程的一套 API)通常是在已有的进程模型中增加的逻辑扩展,所以线程控制和进程控制很相似。而进入内核调度所消耗的性能代价比较高,开销较大。goroutine 是用户态线程,是由 go runtime 管理,创建和销毁的消耗非常小。
goroutine 和 thread 的区别?
调度切换 抛开陷入内核,线程切换会消耗 1000-1500 纳秒(上下文保存成本高,较多寄存器,公平性,复杂时间计算统计),一个纳秒平均可以执行 12-18 条指令。 所以由于线程切换,执行指令的条数会减少 12000-18000。goroutine 的切换约为 200 ns(用户态、3个寄存器),相当于 2400-3600 条指令。因此,goroutines 切换成本比 threads 要小得多。 复杂性 线程的创建和退出复杂,多个 thread 间通讯复杂(share memory)。 不能大量创建线程(参考早期的 httpd),成本高,使用网络多路复用,存在大量callback(参考twemproxy、nginx 的代码)。对于应用服务线程门槛高,例如需要做第三方库隔离,需要考虑引入线程池等。
M:N 模型
Go 创建 M 个线程(CPU 执行调度的单元,内核的 task_struct),之后创建的 N 个 goroutine 都会依附在这 M 个线程上执行,即 M:N 模型。它们能够同时运行,与线程类似,但相比之下非常轻量。因此,程序运行时,Goroutines 的个数应该是远大于线程的个数的(phread 是内核线程?)。 同一个时刻,一个线程只能跑一个 goroutine。当 goroutine 发生阻塞 (chan 阻塞、mutex、syscall 等等) 时,Go 会把当前的 goroutine 调度走,让其他 goroutine 来继续执行,而不是让线程阻塞休眠,尽可能多的分发任务出去,让 CPU 忙。