您好,欢迎来到12图资源库!分享精神,快乐你我!我们只是素材的搬运工!!
  • 首 页
  • 当前位置:首页 > 开发 > WEB开发 >
    几个Go系统能够遇到的锁成绩(2)
    时间:2019-01-07 21:10 来源:网络整理 作者:网络 浏览:收藏 挑错 推荐 打印

    #   0x103f77c   sync.runtime_SemacquireMutex+0x3c                               /usr/local/go/src/runtime/sema.go:71 

    #   0x10714de   sync.(*Mutex).Lock+0xfe                                     /usr/local/go/src/sync/mutex.go:134 

    #   0x1071d8e   sync.(*Pool).pinSlow+0x3e                                   /usr/local/go/src/sync/pool.go:198 

    #   0x1071d25   sync.(*Pool).pin+0x55                                       /usr/local/go/src/sync/pool.go:191 

    #   0x1071a5e   sync.(*Pool).Get+0x2e                                       /usr/local/go/src/sync/pool.go:128 

    #   0x12feeb7   github.com/valyala/fasttemplate/vendor/github.com/valyala/bytebufferpool.(*Pool).Get+0x37   /Users/xargin/go/src/github.com/valyala/fasttemplate/vendor/github.com/valyala/bytebufferpool/pool.go:49 

    #   0x13005ef   github.com/valyala/fasttemplate.(*Template).ExecuteFuncString+0x3f              /Users/xargin/go/src/github.com/valyala/fasttemplate/template.go:278 

    #   0x13007c2   github.com/valyala/fasttemplate.(*Template).ExecuteString+0x52                  /Users/xargin/go/src/github.com/valyala/fasttemplate/template.go:299 

    #   0x130107a   main.loop.func1+0x3a                                        /Users/xargin/test/go/http/httptest.go:22 

    有少量的 Goroutine 会阻塞在获取锁上,为什么呢?继续看看 sync.Pool 的 Get 流程:

    func (p *Pool) Get() interface{} { 

        if race.Enabled { 

            race.Disable() 

        } 

        l := p.pin() 

        x := l.private 

        l.private = nil 

        runtime_procUnpin() 

    然后是 pin:

    func (p *Pool) pin() *poolLocal { 

        pid := runtime_procPin() 

         

        s := atomic.LoadUintptr(&p.localSize) // load-acquire 

        l := p.local                          // load-consume 

        if uintptr(pid) < s { 

            return indexLocal(l, pid) 

        } 

        return p.pinSlow() 

    由于每一个对象的 sync.Pool 都是空的,所以 pin 的流程一定会走到 p.pinSlow:

    func (p *Pool) pinSlow() *poolLocal { 

        runtime_procUnpin() 

        allPoolsMu.Lock() 

        defer allPoolsMu.Unlock() 

        pid := runtime_procPin() 

    而 pinSlow 中会用 allPoolsMu 来加锁,这个 allPoolsMu 主要是为了保护 allPools 变量:

    var ( 

        allPoolsMu Mutex 

        allPools   []*Pool 

    在加了锁的状况下,会把用户重生成的 sync.Pool 对象 append 到 allPools 中:

    if p.local == nil { 

            allPools = append(allPools, p) 

        } 

    (责任编辑:admin)