返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

4.3.2 新建

发布于 2024-10-12 19:15:58 字数 2100 浏览 0 评论 0 收藏 0

每个 G 对象都自带一块栈内存(stack),默认 2 KB。

// stack.go

// The minimum size of stack used by Go code
_StackMin = 2048
// proc.go
func newproc1(fn *funcval, callergp *g, callerpc uintptr) *g {
    
    // 复用或新建。
	newg := gfget(_p_)
	if newg == nil {
		newg = malg(_StackMin)
		casgstatus(newg, _Gidle, _Gdead)
        
		allgadd(newg)
	}
}
// proc.go

// Allocate a new g, with a stack big enough for stacksize bytes.
func malg(stacksize int32) *g {
    
	newg := new(g)
    
	if stacksize >= 0 {
		stacksize = round2(_StackSystem + stacksize)
        newg.stack = stackalloc(uint32(stacksize))

        newg.stackguard0 = newg.stack.lo + _StackGuard
		newg.stackguard1 = ^uintptr(0)
		*(*uintptr)(unsafe.Pointer(newg.stack.lo)) = 0
	}
	return newg
}

所有 G 对象创建后被存入 allgs 内,以供查阅。G 会被复用,但不会销毁。

var (
    
	// allgs contains all Gs ever created (including dead Gs), and thus
	// never shrinks.
	//
	// Access via the slice is protected by allglock or stop-the-world.
	// Readers that cannot take the lock may (carefully!) use the atomic
	// variables below.
    
	allglock mutex
	allgs    []*g

	// allglen and allgptr are atomic variables that contain len(allgs) and
	// &allgs[0] respectively. Proper ordering depends on totally-ordered
	// loads and stores. Writes are protected by allglock.
	//
	// allgptr is updated before allglen. Readers should read allglen
	// before allgptr to ensure that allglen is always <= len(allgptr). New
	// Gs appended during the race can be missed. For a consistent view of
	// all Gs, allglock must be held.
	//
	// allgptr copies should always be stored as a concrete type or
	// unsafe.Pointer, not uintptr, to ensure that GC can still reach it
	// even if it points to a stale array.
    
	allglen uintptr
	allgptr **g
)
func allgadd(gp *g) {

	lock(&allglock)
    
	allgs = append(allgs, gp)
	if &allgs[0] != allgptr {
		atomicstorep(unsafe.Pointer(&allgptr), unsafe.Pointer(&allgs[0]))
	}

	atomic.Storeuintptr(&allglen, uintptr(len(allgs)))
    
	unlock(&allglock)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文