golang sudog指的是什么
更新時間:2024年02月05日 14:29:59 作者:動態(tài)一時爽,重構(gòu)火葬場
sudog代表在等待隊列中的goroutine,比如channel發(fā)送接受,由于goroutine和同步對象的關(guān)系是多對多,因此需要sudog映射,本文重點介紹golang sudog指的是什么,感興趣的朋友一起看看吧
sudog代表在等待隊列中的goroutine,比如channel發(fā)送接受。由于goroutine和同步對象的關(guān)系是多對多,因此需要sudog映射
type sudog struct {
// 指向的goroutine
g *g
// 指向前后sudog的指針
next *sudog
prev *sudog
// 指向數(shù)據(jù)
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的鎖,防止垃圾回收在此期間被調(diào)用
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的鎖,允許垃圾回收調(diào)用
releasem(mp)
return s
}releaseSudog()
func releaseSudog(s *sudog) {
// 判斷sudog各項數(shù)據(jù)、狀態(tài)是否正確
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)
}到此這篇關(guān)于golang sudog是什么?的文章就介紹到這了,更多相關(guān)golang sudog內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Go語言中用 os/exec 執(zhí)行命令的五種方法
這篇文章主要介紹了Go語言中用 os/exec 執(zhí)行命令的五種方法,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11

