golang sudog指的是什么

2024-03-01 0 999

sudog代表在等待队列中的goroutine,比如channel发送接受。由于goroutine和同步对象的关系是多对多,因此需要sudog映射

type sudog struct {
// 指向的goroutine
g *g
// 指向前后sudog的指针
next *sudog
prev *sudog
// 指向数据
elem unsafe.Pointer // data element (may point to stack)
// The following fields are never accessed concurrently.
// For channels, waitlink is only accessed by g.
// For semaphores, all fields (including the ones above)
// are only accessed when holding a semaRoot lock.
// 获取时间
acquiretime int64
// 释放时间
releasetime int64
// 作为队列元素的标识
ticket uint32
// isSelect indicates g is participating in a select, so
// g.selectDone must be CAS\’d to win the wake-up race.
isSelect bool
// success indicates whether communication over channel c
// succeeded. It is true if the goroutine was awoken because a
// value was delivered over channel c, and false if awoken
// because c was closed.
success bool
parent *sudog // semaRoot binary tree
waitlink *sudog // g.waiting list or semaRoot
waittail *sudog // semaRoot
c *hchan // channel
}

acquireSudog()

func acquireSudog() *sudog {
// 增加m的锁,防止垃圾回收在此期间被调用
mp := acquirem()
pp := mp.p.ptr()
// 如果本地缓存为空
if len(pp.sudogcache) == 0 {
lock(&sched.sudoglock)
// 从中心缓存迁移至多一半本地缓存容量的缓存项到本地缓存
for len(pp.sudogcache) < cap(pp.sudogcache)/2 && sched.sudogcache != nil {
s := sched.sudogcache
sched.sudogcache = s.next
s.next = nil
pp.sudogcache = append(pp.sudogcache, s)
}
unlock(&sched.sudoglock)
// 若本地缓存仍为空,则新建缓存项
if len(pp.sudogcache) == 0 {
pp.sudogcache = append(pp.sudogcache, new(sudog))
}
}
// 从本地缓存中取出最后一个缓存项返回
n := len(pp.sudogcache)
s := pp.sudogcache[n-1]
pp.sudogcache[n-1] = nil
pp.sudogcache = pp.sudogcache[:n-1]
if s.elem != nil {
throw(\”acquireSudog: found s.elem != nil in cache\”)
}
// 减少m的锁,允许垃圾回收调用
releasem(mp)
return s
}

releaseSudog()

func releaseSudog(s *sudog) {
// 判断sudog各项数据、状态是否正确
if s.elem != nil {
throw(\”runtime: sudog with non-nil elem\”)
}
if s.isSelect {
throw(\”runtime: sudog with non-false isSelect\”)
}
if s.next != nil {
throw(\”runtime: sudog with non-nil next\”)
}
if s.prev != nil {
throw(\”runtime: sudog with non-nil prev\”)
}
if s.waitlink != nil {
throw(\”runtime: sudog with non-nil waitlink\”)
}
if s.c != nil {
throw(\”runtime: sudog with non-nil c\”)
}
gp := getg()
if gp.param != nil {
throw(\”runtime: releaseSudog with non-nil gp.param\”)
}
mp := acquirem() // avoid rescheduling to another P
pp := mp.p.ptr()
// 如果本地缓存满了,就迁移至多一半容量缓存项到中心缓存
if len(pp.sudogcache) == cap(pp.sudogcache) {
// Transfer half of local cache to the central cache.
var first, last *sudog
for len(pp.sudogcache) > cap(pp.sudogcache)/2 {
n := len(pp.sudogcache)
p := pp.sudogcache[n-1]
pp.sudogcache[n-1] = nil
pp.sudogcache = pp.sudogcache[:n-1]
if first == nil {
first = p
} else {
last.next = p
}
last = p
}
lock(&sched.sudoglock)
// 将迁移出来的本地缓存链表直接挂到中心缓存中
last.next = sched.sudogcache
sched.sudogcache = first
unlock(&sched.sudoglock)
}
// 将释放的sudog添加到本地缓存
pp.sudogcache = append(pp.sudogcache, s)
releasem(mp)
}

到此这篇关于golang sudog是什么?的文章就介绍到这了,更多相关golang sudog内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源网!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Golang golang sudog指的是什么 https://www.u-9.cn/jiaoben/golang/179331.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务