数据段
全局变量 g0。m0
协程对应的数据结构是runtime.g,工作线程对应的是runtime.m,全局变量g0就是主协程对应的g,全局变量m0就是主线程对应的m与其他协程不同的是,他的协程栈 是由主线程栈上分配的G0 持有m0的指针,m0 也记录着g0的指针,而且一开始m0上执行的协程正是g0全局变量allgs记录着所有的g,allm用于记录所有的m.全局变量sched(代表的是调度器,数据结构示runtime.schedt,记录所有空闲的m,空闲的p,全局队列runq等)全局变量allp记录所有的P一开始调度模型只有MG,但是因为频繁的加锁和解锁带来很大的资源消耗
每个M和本地的自己的P绑定,这样可以避免只有一个p带来的加锁和解锁的性能消耗还有一个全局队列P,用于所有的P满了之后放入全局P中M先从关联的本地队列中获取,如果没有的话在到全局队列领取一些任务,全局都没有就会随机窃取其他P的任务放入本地队列p的创建过程
全局变量allp记录所有的p程序初始化的时候会进行调度器初始化,这时会根据GOMAXPROCS环境变量来创建P的个数,并将allp[0]和m[0]绑定建立关系main goroutin创建之前GPM关系
程序初始化
队列里只有main goutine 切换到main goutine执行入口是runtime.main,会创建监控线程,进行包初始化等,然后调用main.main,输出hello word在mian.main返回之后会调用exit()退出结束进程通过协程输出hello word过程
当main.main被执行时就会创建一个新的goroutie会被编译器转为newproc函数调用,调用时,之后给入口和参数,而newproc函数会给goroutine创建一个栈帧,目的是让协程结束后,返回到goexit中,进行协程资源回收协程返回以后怎么样了
协程返回后怎么样了,是被回收了吗
如果只有一个main.goroutine,那么执行完毕后后调用exit函数,释放空间内存,进行资源回收
时候time.sleep 会将main.goroutine放入等待队列,为waiting状态,其他写成得以执行,等到sleep执行之后,time会把main goroutine重新置为——Grunnable状态,放回到runq的队列中,再然后就结束了,exit调用,进程退出,这是只有一个p的情况
创建多个p的退出
默认会加到当前p的本地队列有空闲p的情况下,就可以启动新的线程关联这个p,并把hello goroutine 放入到本地队列中=