Advanced Go
GMP
协程
协程是用户态的概念。多个协程实际上映射为1个线程。
协程是用户态概念,因此创建、销毁、调度都在用户态完成,不需要切换内核态。
由于协程从属于同一个内核级线程,因此实际上无法并行;而一个协程的阻塞最终也会导致整个线程下的所有协程阻塞。
Goroutine
Go解耦了协程和线程的绑定关系,从而使线程变为一个中间层,协程可以灵活地映射到不同的线程上,相当于“虚拟线程”。
好处如下:
- 可以利用多个线程,实现并行
- 通过调度器,实现灵活的映射
- 栈空间动态扩展(线程大小固定,会产生内存浪费)
GMP
Goroutine Machine Processor
GMP就是协程调度器。
GMP有一个全局队列存储Goroutine;不过实际上Processor都会优先在自己的本地队列调度Goroutine(没有则向全局队列获取),并映射Goroutine到Machine上执行。
如果全局队列没有Goroutine,那么会尝试获取就绪态(正在IO)的协程。
如果仍然失败,那么会从其他Processor中窃取一半的Goroutine,实现负载均衡。
全局队列是互斥的,获取Goroutine要防止获取多次。
type schedt struct { |