golang sudog指的是什么
sudog代表在等待隊(duì)列中的goroutine,比如channel發(fā)送接受。由于goroutine和同步對(duì)象的關(guān)系是多對(duì)多,因此需要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. // 獲取時(shí)間 acquiretime int64 // 釋放時(shí)間 releasetime int64 // 作為隊(duì)列元素的標(biāo)識(shí) 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) // 從中心緩存遷移至多一半本地緩存容量的緩存項(xiàng)到本地緩存 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) // 若本地緩存仍為空,則新建緩存項(xiàng) if len(pp.sudogcache) == 0 { pp.sudogcache = append(pp.sudogcache, new(sudog)) } } // 從本地緩存中取出最后一個(gè)緩存項(xiàng)返回 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各項(xiàng)數(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() // 如果本地緩存滿了,就遷移至多一半容量緩存項(xiàng)到中心緩存 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)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語(yǔ)言中Timer和Ticker兩種計(jì)時(shí)器的使用
go語(yǔ)言中有Timer和Ticker這樣的兩種計(jì)時(shí)器,兩種計(jì)時(shí)器分別實(shí)現(xiàn)了不同的計(jì)時(shí)功能,本文主要介紹了go語(yǔ)言中Timer和Ticker兩種計(jì)時(shí)器的使用,感興趣的可以了解一下2024-08-08一文教你學(xué)會(huì)Go中singleflight的使用
緩存在項(xiàng)目中使用應(yīng)該是非常頻繁的,提到緩存只要了解過?singleflight?,基本都會(huì)用于緩存實(shí)現(xiàn)的一部分吧,下面就跟隨小編一起來學(xué)習(xí)一下singleflight的使用吧2024-02-02詳解Go語(yǔ)言中用 os/exec 執(zhí)行命令的五種方法
這篇文章主要介紹了Go語(yǔ)言中用 os/exec 執(zhí)行命令的五種方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11