赞
踩
1.1 协程的定义
- 在go语言中,协程被认为是轻量级的线程, 和线程不同的是,操作系统内核
感知不到协程的存在, 协程的管理依赖于Go语言运行时自身提供的调度器
同时Go语言中的协程是从属于某一个线程的。1.2协程的调度方式
- 协程是用户态的。协程的管理依赖Go语言运行时的调度器。同时,Go语言中的协程是从属于某一个线程的,协程与线程的对应关系为M:N,即多对多 .如图所示, Go语言调度器可以将多个协程调度到一个线程中,一个协程也可能切换到多个线程中执行。
1.3协程之间的切换
- 1.协程的速度要快于线程
2.其原因在于协程切换不用经过操作系统用户态与内核态的切换
3.并且Go语言中的协程切换只需要保留极少的状态和寄存器变量值
4.而线程切换会保留额外的寄存器变量值(例如浮点数寄存器)1.4调度策略
- 线程之间的调度大部分是抢占式的,协程的调度是一般是协作式的调度(当一个协程处理完自己的任务后,可以主动将执行权限让渡给其他协程)
1.5 栈空间大小
- 线程一般是固定的栈大小,go采用了动态扩张收缩的策略。
- GMP调度
- G(Goroutine): 即Go协程,每个go关键字都会创建一个协程。M (Machine): 工作线程,内核线程。P (Processor): 处理器 【go定义的一个概念,不是指CPU】,包含运行Go代码的主要资源,也有调度goroutine的能力,一般是CPU的内核数。
- 每个P中包含一个local run queue的goroute队列,调度器中包含一个全局的goroute队列。
- Java中国的线程对应一个内核线程,go中是多对多的关系,增大了并发度。
- 其主要作用是在 goroutine 中进行上下文的传递,在传递信息中又包含了 goroutine 的运行控制、上下文信息传递等功能。
- context 与 select-case 联合,还可以实现上下文的截止时间、信号控制、信息传递等跨 goroutine 的操作,是 Go 语言协程的重要组成部分。
- Go语言的GC演进:Go1.0仅支持串行 → Go1.1可以并行 → Go1.3 精确STW →Go1.5 三色并发+屏障→ Go1.8 混合写屏障。
- Go中GC详细描述
标记清除法
- 标记阶段—>清除阶段
三色标记法
- 新建对象是白色,开始gc的时候,从root开始遍历所有的对象,将遍历到的对象放入灰色集合中,在对灰色集合进行遍历,将灰色对象引用的对象从白盒放入灰盒,并把此对虾干从灰盒放到黑盒。重复上述步骤,直到灰盒中没有对象,回收白盒。
屏障机制
- “强-弱” 三色不变式
1.强三色不变式:不存在黑色对象引用到白色对象的指针。
2.弱三色不变式:所有被黑色对象引用的白色对象都处于灰色保护状态 【即白色对象存在灰色引用】。总结
- Go1.3版本之前,使用的是普通标记清除法,整体过程需要启动STW,GC性能极差。
- Go1.3版本,使用的是简单优化的标记清除法,通过将STW的时间提前,GC性能略有提升。
- Go1.5版本, 使用改进版的标记清除算法——三色标记法,堆空间启动写屏障,栈空间不启动,全部扫描之后,需要重新扫描一次栈(这时需要STW),GC性能提升较大。
- Go1.8版本,三色标记法,混合写屏障机制, 栈空间不启动,堆空间启动。整个过程几乎不需要STW,GC性能提升很大。
- 相同点:epoll和select都是多路复用下的一种机制,多路复用I/O就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪,就通知程序该文件描述符可以进行读写操作。
- select():用于确定一个或多个套接口的状态。
select的几大缺点(不可忽视):
1、每次调用select()的时候,都必须要将fd从用户态转换成内核态,这个开销在fd很多的时候非常大。
2、调用select()的时候,在操作系统内核API都会遍历整个fd集,这会大大影响系统效率。
3、select()可打开的文件描述符的上限太少了,默认是1024个。- epoll不用每次遍历fd,只有初始化的时候遍历+基于事件回调的方式获取fd,epoll可打开的文件没有上线。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。