golang篇-2021秋招准备
1、GPM
G(Goroutine) :我们所说的协程,为用户级的轻量级线程,每个Goroutine对象中的sched保存着其上下文信息
M(Machine) :对内核级线程的封装,数量对应真实的CPU数(真正干活的对象)
P(Processor)
- 即为G和M的调度对象,用来调度G和M之间的关联关系,其数量可通过GOMAXPROCS()来设置,默认为核心数
- P为M的执行提供了上下文,保存了M执行G的一些基本信息,保存了等待执行的G队列……
M只有绑定P才可以去执行G
每个Processor对象都拥有一个LRQ(Local Run Queue),未分配的Goroutine对象保存在GRQ(Global Run Queue )中,等待分配给某一个P的LRQ中,每个LRQ里面包含若干个用户创建的Goroutine对象,同时Processor作为桥梁对Machine和Goroutine进行了解耦,也就是说Goroutine如果想要使用Machine需要绑定一个Processor才行,上图中共有两个M和两个P也就是说我们可以同时并行处理两个goroutine
2、Channel
无缓冲channel与有缓冲channel
无缓冲的是默认,同步
缓冲是1的缓冲式,异步
其实是彻底错误的,无缓冲的与有缓冲channel有着重大差别
比如
1 | c1:=make(chan int) 无缓冲 |
无缓冲的通道保证进行发送和接收的 goroutine 会在同一时间进行数据交换;有缓冲的通道没有这种保证
无缓冲的 不仅仅是向c1通道放 1 而是 一直要有别的协程 <-c1 接手了 这个参数,那么c1<-1才会继续下去,要不然就一直阻塞着
c2<-1 则不会阻塞,因为缓冲大小是1 (其实是缓冲大小为0)只有当放第二个值的时候 第一个还没被人拿走,这时候才会阻塞
通道关闭:关闭通道的代码非常重要。当通道关闭后,goroutine 依旧可以从通道接收数据,但是不能再向通道里发送数据。能够从已经关闭的通道接收数据这一点非常重要,因为这允许通道关闭后依旧能取出其中缓冲的全部值,而不会有数据丢失。从一个已经关闭且没有数据的通道里获取数据,总会立刻返回,并返回一个通道类型的零值。如果在获取通道时还加入了可选的标志,就能得到通道的状态信息。