课程章节:5-1,5-2,5-3
课程讲师:Moody
课程内容:
※ runtime中,协程的本质是一个g结构体
※g结构体中有一些重要的成员:
· stack : 堆栈地址,存储低地址和高地址,从低地址到高地址是整个g协程所占用的栈空间
· gobuf: 目前协程运行现场
· sp : StackPoint 栈地址,当前运行的栈地址
· pc : 程序计数器
· atomicstatus : 协程状态
· goid :该协程的编号id
简单的来说协程的本质就是,这段代码在哪里,执行到哪里了,执行的怎么样了。
※ go对线程的描述是 m 结构体,有几个重要的成员:
· g0 *g : go初始的第一个协程,用于调用其他协程
· curg *g :线程当前运行的协程g
※协程为什么快:
协程的速度之所以会比线程快,是因为协程切换不需要经过操作系统用户态和内核态的切换,并且go语言的协程切换只需要保留极少的状态和寄存器变量值,而相比之下的线程,会保存额外的寄存器的变量值,线程切换在1~2微秒,go的协程切换只需要0.2微秒
※并发并非是并行
并发说的是程序同时执行多个任务的能力,一段时间内,所有的任务都能执行完毕,执行并不具备排他性。
※main函数是一个特殊的协程,当主协程退出的时候,程序直接退出。
※调度策略
线程的调度多为抢占式,操作系统为均衡每个线程的资源,会发出信号中断执行,切换上下文。go的协程是协作试调度,当一个协程执行完自己的任务后,会主动让出资源给其他协程,如果一个协程执行时间过长,才会被调度器中断。
※栈大小:
线程栈大小一般是创建的时候指定的,为避免溢出,默认栈较大,比如2mb。这意味着1000个线程就要消耗接近2G内存,而go的协程默认是2kb,在需要的时候进行动态扩容。