(1)pin 方法内部通过 native 方法 runtime_procPin 取出当前 P 的 index,并且将当前 goroutine 与 P 进行绑定,短暂处于不可抢占状态; (2)如果是首次调用 pin 方法,则会走进 pinSlow 方法; (3)在pinSlow 方法中,会完成 Pool.local 的初始化,并且将当前 Pool 添加到全局
必须与runtime_procUnpin搭配使用 该函数Put和Get均会调用 func (p *Pool) pin() (*poolLocal, int) { // 与runtime_procUnpin搭配使用 pid := runtime_procPin() // In pinSlow we store to local and then to localSize, here we load in opposite order. // Since we've disabled preemption, ...
调用runtime_procPin方法: 会先获取当前G,然后绑定到对应的M上,然后返回M目前绑定的P的id 原子操作取出localSize 如果pid小于localSize,调用indexLocal取出pid对应的poolLocal返回 否则就表示Pool还没创建对应的poolLocal,调用pinSlow进行创建。 func (p *Pool) pin() (*poolLocal, int) { pid := runtime_procP...
return p.pinSlow() } 1. 2. 3. 4. 5. 6. 7. 8. 9. • pin 方法内部通过 native 方法 runtime_procPin 取出当前 P 的 index,并且将当前 goroutine 与 P 进行绑定,短暂处于不可抢占状态; • 如果是首次调用 pin 方法,则会走进 pinSlow 方法; • 在pinSlow 方法中,会完成 Pool.local 的...
runtime_procUnpin() ifrace.Enabled { race.Enable() } } 所以我们看到 Put 的操作很简单,就是单纯地放回 Pool 中,涉及到不同的存放位置。基本上可以总结为下面的操作流程: 1、首先调用 p.pin() 抢占p,获取 localpool 2、优先放归还到private中 ...
func(p *Pool)pinSlow() (*poolLocal,int) {// 调用pinSlow前, 必定调用了pin, 暂时释放, 因为在pin的过程中, 无法对互斥锁进行操作runtime_procUnpin()// 初始化local, 禁止并发访问allPoolsMu.Lock()deferallPoolsMu.Unlock()// 重新pinpid := runtime_procPin()// poolCleanup 在pin的过程中, GC...
runtime_procUnpin() allPoolsMu.Lock() defer allPoolsMu.Unlock() pid := runtime_procPin() // poolCleanup won't be called while we are pinned. // 再次检查是否LocalPool是否有对应的索引,避免其他的线程造成影响 s := p.localSize l := p.local ...
Unlock() pid := runtime_procPin() s := p.localSize l := p.local if uintptr(pid) < s { // pinSlow是一个创建local的方法。在获得allPoolsMu锁前,可能被别的P先获取,这种情况下local就已经被初始化了 // 所以在获得allPoolsMu锁后需要再检查一次uintptr(pid) < s return indexLocal(l, pid...
runtime_procUnpin() } 从以上代码可以看到,在 Put 函数中首先调用了pin()。pin函数非常重要,它有三个作用: 初始化或者重新创建local数组。当 local 数组为空,或者和当前的runtime.GOMAXPROCS不一致时,将触发重新创建 local 数组,以和 P 的个数保持一致。
func (p *Pool) getSlow() (x interface{}) {// See the comment in pin regarding ordering of the loads.size := atomic.LoadUintptr(&p.localSize) // load-acquirelocal := p.local // load-consume// Try to steal one element from other procs.pid := runtime_procPin()runtime_procUnpin...