主协程初始化
Golang的主协程指的是运行main函数的协程,而子协程指的是在程序运行过程中由主协程创建的协程。每个线程(m)只会有一个主协程,而子协程可能会有很多很多。
子协程和主协程在概念和内部实现上几乎没有任何区别,唯一的不同在于它们的初始栈大小不同。
我们先看看测试过程中生成的主协程堆栈示例。我测试代码中就生成了一个主协程,通过反汇编代码看到他的样子大概如下:
主协程启动
分析连接器(libinit())发现go程序的入口函数是_rt0_amd64_linux(linux amd64机器)
子协程初始化
Golang子协程堆栈在协程被创建时也一并创建,代码如下:
在go1.5.1版本中,_StackMin大小被定义为2048(而在1.3.2版本中该值还是8192),也即每个协程的初始堆栈大小为2KB,相当小了。缩小该值的好处是即使创建了很多的协程也不会导致内存使用的急剧增长。
另外,在协程栈空间被分配出来后,还需要作一些其他的初始化,主要是协程栈顶的设置以及堆栈保护的设置。
栈顶的设置方法比较简单,将当前栈的起始地址减去参数占用的空间即可(注意栈是从高地址向低地址延伸的)。
栈保护的设置指的是设置一个临界点,当sp到达该临界点时认为栈空间可能会不足,需要进行栈扩容。当前版本的协程栈保护大小事640B。
以下是我对源码加入一些调试信息后打印的协程创建堆栈的详细信息:
根据上面的分析以及打印信息可以大致勾勒出协程初始化状态的堆栈:
https://tracymacding.gitbooks.io/implementation-of-golang/stack/stack_overview.html https://tracymacding.gitbooks.io/implementation-of-golang/stack/stack_enlarge.html到此这篇关于“Golang协程栈初始化”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!
您可能感兴趣的文章:
探索Golang协程实现——从v1.0开始
golang float32转float64精度丢失_golang 混合写屏障原理深入剖析,这篇文章给你梳理的明明白白!...
go 开了多少个goroutine 怎么看_Golang 协程Goroutine到底是怎么回事?(一)
golang debug 配置_缓存击穿导致 golang 组件死锁的问题分享
golang key map 所有_缓存击穿导致 golang 组件死锁的问题分享
golang 解题标准括号问题
Golang教程:goroutine协程
golang面试题
Go语言(golang)常见问题总结(一)
golang 常见面试基础(1)