Semaphore 数据布局解析详解
副问题[/!--empirenews.page--]
// Go 说话中袒露的 semaphore 实现 // 详细的用法是提供 sleep 和 wakeup 原语 // 以使其可以或许在其余同步原语中的竞争环境下行使 // 因此这里的 semaphore 和 Linux 中的 futex 方针是同等的 // 只不外语义上更简朴一些 // // 也就是说,不要以为这些是信号量 // 把这里的对象看作 sleep 和 wakeup 实现的一种方法 // 每一个 sleep 城市和一个 wakeup 配对 // 纵然在产生 race 时,wakeup 在 sleep 之前时也是云云 // // See Mullender and Cox, ``Semaphores in Plan 9,'' //
// 为 sync.Mutex 筹备的异步信号量
// semaRoot 持有一棵 地点各不沟通的 sudog(s.elem) 的均衡树 // 每一个 sudog 都反过来指向(通过 s.waitlink)一个在统一个地点上守候的其余 sudog 们 // 统一地点的 sudog 的内部列表上的操纵时刻伟大度都是 O(1)。顶层 semaRoot 列表的扫描 // 的时刻伟大度是 O(log n),n 是被哈希到统一个 semaRoot 的差异地点的总数,每一个地点上城市有一些 goroutine 被阻塞。 // 会见 golang.org/issue/17953 来查察一个在引入二级列表之前机能较差的措施样例,test/locklinear.go // 中有一个复现这个样例的测试 type semaRoot struct { lock mutex treap *sudog // root of balanced tree of unique waiters. nwait uint32 // Number of waiters. Read w/o the lock. }
// Prime to not correlate with any user patterns. const semTabSize = 251
var semtable [semTabSize]struct { root semaRoot pad [sys.CacheLineSize - unsafe.Sizeof(semaRoot{})]byte }
func semroot(addr *uint32) *semaRoot { return &semtable[(uintptr(unsafe.Pointer(addr))>>3)%semTabSize].root } ┌─────┬─────┬─────┬─────┬─────┬────────────────────────┬─────┐ │ 0 │ 1 │ 2 │ 3 │ 4 │ ..... │ 250 │ └─────┴─────┴─────┴─────┴─────┴────────────────────────┴─────┘ │ │ │ │ (编辑:湖南网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |